Reputation: 45
I have a string that I regex which returns me a tuple (see results printed) and I want to create a dictionary from it (first entry of tuple is key, second is value), which according to StackOverflow posts should work like a charm. The for loop can return multiple points which each should be added to a single dict that should be returned.
Code & Error:
import re as re
n = nuke.selectedNode()
k = n.knob('scene')
script = k.toScript().replace('\n','').split('scenegraph {')
for sgrph in script:
for m in [re.match(r".*\bname '([Point\d]+)'.*\btransform ([0-9.e+\- ]+)",sgrph)]:
if m is not None:
print m.groups()
items = dict(m.groups()) #this causes the error
print "........."
print items
Output:
# Result: ('Point1', '1.983990908e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 1.983990908e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 0.000000000e+00 1.983990908e+00 0.000000000e+00 5.610483289e-01 6.365304199e+03 4.553408813e+02 1.000000000e+00 ')
Traceback (most recent call last):
File "<string>", line 11, in <module>
ValueError: dictionary update sequence element #0 has length 6; 2 is required
Upvotes: 3
Views: 225
Reputation: 6709
Dict in python can be created from the iterable of (key, value)
pairs. But you have a flat tuple of values as a result of m.groups()
call. You need to pick even elements of this tuple as keys and then odd elements as corresponding values and then zip
them together:
values = ('foo', 'bar', 'qux', 'blah')
dict(zip(values[::2], values[1::2]))
Here is an example using re.match().groups()
:
import re
match = re.match(r'(\d+) (\d+) (\d+) (\d+)', '12 34 56 78')
groups = match.groups() # gives ('12', '34', '56', '78')
dict(zip(groups[::2], groups[1::2])) # gives {'56': '78', '12': '34'}
UPD: Be aware that zip
produces the sequence with the length truncated to the shortest length of its input. So if m.groups()
returned odd number of elements the last value will not occur in the resulting dict.
Upvotes: 0
Reputation: 164773
In my opinion, it's a good idea to be explicit. For example, you can define your dictionary before your nested for
loops, unpack explicitly and add an item to your dictionary.
res = {}
for sgrph in script:
for m in [re.match(r".*\bname '([Point\d]+)'.*\btransform ([0-9.e+\- ]+)",sgrph)]:
if m is not None:
key, value = m.groups()
res[key] = value
Upvotes: 1