How to turn a list into nested dict in Python

前端 未结 4 1354
感情败类
感情败类 2020-12-28 21:31

Need to turn x:

X = [[\'A\', \'B\', \'C\'], [\'A\', \'B\', \'D\']]

Into Y:

Y = {\'A\': {\'B\': {\'C\',\'D\'}}}
相关标签:
4条回答
  • 2020-12-28 22:07
    X = [['A', 'B', 'C'], ['A', 'B', 'D'],['W','X'],['W','Y','Z']]
    d = {}
    
    for path in X:
        current_level = d
        for part in path:
            if part not in current_level:
                current_level[part] = {}
            current_level = current_level[part]
    

    This leaves us with d containing {'A': {'B': {'C': {}, 'D': {}}}, 'W': {'Y': {'Z': {}}, 'X': {}}}. Any item containing an empty dictionary is either a file or an empty directory.

    0 讨论(0)
  • 2020-12-28 22:08

    This should be pretty close to what you need:

    def path_to_dict(path):
        parts = path.split('/')
    
        def pack(parts):
            if len(parts) == 1:
                return parts
            elif len(parts):
                return {parts[0]: pack(parts[1:])}
            return parts
    
        return pack(parts)
    
    if __name__ == '__main__':
        paths = ['xyz/123/file.txt', 'abc/456/otherfile.txt']
        for path in paths:
            print '%s -> %s' % (path, path_to_dict(path))
    

    Results in:

    xyz/123/file.txt -> {'xyz': {'123': ['file.txt']}}
    abc/456/otherfile.txt -> {'abc': {'456': ['otherfile.txt']}}
    
    0 讨论(0)
  • 2020-12-28 22:22

    There is a logical inconsistency in your problem statement. If you really want ['xyz/123/file.txt', 'abc/456/otherfile.txt']

    to be changed to {'xyz': {'123': 'file.txt}, 'abc': {'456': 'otherfile.txt'}}

    Then you have to answer how a path 'abc.txt' with no leading folder would be inserted into this data structure. Would the top-level dictionary key be the empty string ''?

    0 讨论(0)
  • 2020-12-28 22:23

    Assuming that {'C', 'D'} means set(['C', 'D']) and your Python version supports dict comprehension and set comprehension, here's an ugly but working solution:

    >>> tr = [[1, 2, 3], [1, 2, 4], [5, 6, 7]]
    >>> {a[0]: {b[1]: {c[2] for c in [y for y in tr if y[1] == b[1]]} for b in [x for x in tr if x[0] == a[0]]} for a in tr}
    {1: {2: set([3, 4])}, 5: {6: set([7])}}
    

    As for your example:

    >>> X = [['A', 'B', 'C'], ['A', 'B', 'D']]
    >>> {a[0]: {b[1]: {c[2] for c in [y for y in X if y[1] == b[1]]} for b in [x for x in X if x[0] == a[0]]} for a in X}
    {'A': {'B': set(['C', 'D'])}}
    

    But please don't use it in a real-world application :)

    UPDATE: here's one that works with arbitrary depths:

    >>> def todict(lst, d=0):
    ...     print lst, d
    ...     if d > len(lst):
    ...         return {}
    ...     return {a[d]: todict([x for x in X if x[d] == a[d]], d+1) for a in lst}
    ...
    >>> todict(X)
    {'A': {'B': {'C': {}, 'D': {}}}}
    
    0 讨论(0)
提交回复
热议问题