简体   繁体   English

python数据结构:字典列表到一个字典

[英]python data structure: list of dict to one dict

I have a data structure.我有一个数据结构。 It looks as follows:它看起来如下:

data = [[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-A', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-B', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-C', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-D', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3C', 'name': 'grandChild-E', 'steps': 2},
 {'id': '4A', 'name': 'final', 'steps': 3}
 ],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2', 'name': 'child', 'steps': 1},
 ]
]

How my expected output is我的预期输出如何

expected output预期产出

output = {
    "1" : {
        "2A": {
            "3A": "grandChild-A",
            "3B": "grandChild-B"

        },
        "2B": {
            "3A": "grandChild-C",
            "3B": "grandChild-D",
            "3C": {
                "4A": "final"
            }

        },
        "2":"child"

    }
}

How can I do that?我怎样才能做到这一点? I wanted to use the enumerator, But I always everything inside 1. Thanks in advance我想使用枚举器,但我总是把所有的东西都放在 1 里面。提前致谢

Update:更新:

I have tried the following code:我尝试了以下代码:

parent = data[0][0]["id"]
dict_new = {}
dict_new[parent] = {}

for e in data:
    for idx, item in enumerate(e):
        display(item)
        if idx>0:
            dict_new[parent][e[idx]["id"]] = e[idx]["name"]

You can try:你可以试试:

d = {}
root = d
for L in data:
    d = root
    for M in L[:-1]:
        d = d.setdefault(M["id"], {})
    d[L[-1]["id"]] = L[-1]['name']

The idea is to follow each list to build a tree (thus d.setdefault(M["id"], {}) . The leaf is handled differently, because it has to be the value of 'name'.这个想法是按照每个列表构建一棵树(因此d.setdefault(M["id"], {}) 。叶子的处理方式不同,因为它必须是 'name' 的值。

from pprint import pprint
pprint(root)

Output:输出:

{'1': {'2': 'child',
       '2A': {'3A': 'grandChild-A', '3B': 'grandChild-B'},
       '2B': {'3A': 'grandChild-C',
              '3B': 'grandChild-D',
              '3C': {'4A': 'final'}}}}

The solution above won't work for the following input:上述解决方案不适用于以下输入:

data = [[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1}]],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-C', 'steps': 2}]]

Iterating over the second list will try to add a new element 3A -> grandChild-C to the d['1']['2B'] dict.迭代第二个列表将尝试将新元素3A -> grandChild-Cd['1']['2B'] dict。 But d['1']['2B'] is not a dict but the 'child' string here, because of the first list.但是d['1']['2B']不是字典而是这里的'child'字符串,因为第一个列表。

When we iterate over the elements, we check if the key is already mapped and otherwise create a new dict (that's the setdefault job).当我们迭代元素时,我们检查键是否已经被映射,否则创建一个新的字典(这是setdefault作业)。 We can also check if the key was mapped to a str , and if that's the case, replace the string by a fresh new dict:我们还可以检查键是否映射到str ,如果是这种情况,请用新的字典替换字符串:

...
for M in L[:-1]:
    if M["id"] not in d or isinstance(d[M["id"]], str):
        d[M["id"]] = {}
    d = d[M["id"]]
...

Output:输出:

{'1': {'2B': {'3A': 'grandChild-C'}}}

I fixed your data: (missing comma)我修复了您的数据:(缺少逗号)

data = [[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-A', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2A', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-B', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3A', 'name': 'grandChild-C', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3B', 'name': 'grandChild-D', 'steps': 2}],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2B', 'name': 'child', 'steps': 1},
 {'id': '3C', 'name': 'grandChild-E', 'steps': 2},
 {'id': '4A', 'name': 'final', 'steps': 3}
 ],

[{'id': '1', 'name': 'parent', 'steps': 0},
 {'id': '2', 'name': 'child', 'steps': 1},
 ]
]

And I came up with this code:我想出了这个代码:

output = {}
#print(data)

for lis in data:
    o = output
    ln = len(lis) - 1
    for idx,d in enumerate(lis):
        id = d['id']
        if idx == ln:
            o[id] = d['name']
        else:
            if id not in o:
                o[id] = {}
            o = o[id]

print('Result:')
print(output)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM