Reputation: 11066
I have data like so (yes, these tuples are guaranteed to have exactly 5 elements):
ts = ([('a','b','c','d','e'), ('v','w','x','y','z'),
('f','g','h','i','j'), ('a','foo','bar',1,2),
('f','g','baz',1,3), ('f','g','baz',3,4)])
I'm trying to parse it into a nested dictionary structure like so:
d = {
'a': {
'b': {
'c': [('d','e')]
},
'foo': {
'bar': [(1,2)]
}
},
'f': {
'g': {
'h': [('i', 'j')],
'baz': [(1,3), (3,4)]
}
},
'v': {
'w': {
'x': [('y', 'z')]
}
}
}
Here's what I have so far; it seems to work properly:
>>> d = {}
>>> for t in ts:
... if t[0] not in d:
... d[t[0]] = {t[1]: {t[2]: [(t[3], t[4])]}}
... elif t[1] not in d[t[0]]:
... d[t[0]][t[1]] = {t[2]: [(t[3], t[4])]}
... elif t[2] not in d[t[0]][t[1]]:
... d[t[0]][t[1]][t[2]] = [(t[3], t[4])]
... else:
... d[t[0]][t[1]][t[2]].append((t[3],t[4]))
...
>>> d
{'a': {'b': {'c': [('d', 'e')]}, 'foo': {'bar': [(1, 2)]}}, 'f': {'g': {'h': [('i', 'j')], 'baz': [(1, 3), (3, 4)]}}, 'v': {'w': {'x': [('y', 'z')]}}}
When I attempted this comprehension, of course, some of the values got overwritten:
>>> {t[0]: {t[1]: {t[2]: [(t[3],t[4])]}} for t in ts}
{'a': {'foo': {'bar': [(1, 2)]}}, 'f': {'g': {'baz': [(3, 4)]}}, 'v': {'w': {'x': [('y', 'z')]}}}
And you really don't want to see the result of this:
>>> {t[0]: {t[1]: {t[2]: [(t[3],t[4])] for t in ts} for t in ts} for t in ts}
How do I correctly write this dict comprehension?
Edit: I'm sorry, I forgot to mention - I need this to be a regular dictionary at the end of the day (it's getting converted to an NSDictionary
via PyObjC eventually).
Upvotes: 0
Views: 164
Reputation: 104762
I'd set up the dictionary automatically built its own nested structure as needed:
from collections import defaultdict
dct = defaultdict(lambda: defaultdict(lambda: defaultdict(list)))
Then just append the 2-tuples into the right list:
for a, b, c, d, e in ts:
dct[a][b][c].append((d, e))
If the different levels of indexing have meanings, I'd use better names than a
, b
, c
though.
Upvotes: 5