문제

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).

도움이 되었습니까?

해결책

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.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top