Python (递归地)从列表列表中构建一个字典,然后了解它的深度。
我有一系列节点,如:Python (递归地)从列表列表中构建一个字典,然后了解它的深度。,python,recursion,nested,Python,Recursion,Nested,我有一系列节点,如: nodes = [['mid2', 'top1'], ['low2', 'mid2'], ['mid3', 'top2'], ['low1', 'mid1'], ['top1', None], ['top2', None], ['low3', 'mid3'], ['mid1', 'top1']] 它们需要像这样: desired_result = { "top1": { "mid1": { "low1": {}
nodes = [['mid2', 'top1'],
['low2', 'mid2'],
['mid3', 'top2'],
['low1', 'mid1'],
['top1', None],
['top2', None],
['low3', 'mid3'],
['mid1', 'top1']]
它们需要像这样:
desired_result = {
"top1": {
"mid1": {
"low1": {}
},
"mid2": {
"low2": {}
}
},
"top2": {
"mid3": {
"low3": {}
}
}
}
因为列表中的每个项目只有2个元素,所以我很难从头开始构建树。我可以构建前2层,但是添加第3层(或者将来,第4层)节点非常困难
另外,在最后,我需要能够找出一个节点在树中有多少层。这样做的最佳方法是通过简单地遍历树并创建索引,还是可以任意执行?这是一个有趣的问题,因此我编写了一些代码,即使您没有提供:
from collections import defaultdict
nodes_with_children = defaultdict(list)
nodes = [['mid2', 'top1'],
['low2', 'mid2'],
['mid3', 'top2'],
['low1', 'mid1'],
['top1', None],
['top2', None],
['low3', 'mid3'],
['mid1', 'top1']]
for child, parent in nodes:
nodes_with_children[parent].append(child)
print nodes_with_children
# defaultdict(<type 'list'>, {'top2': ['mid3'], 'top1': ['mid2', 'mid1'],
# None: ['top1', 'top2'], 'mid2': ['low2'], 'mid3': ['low3'], 'mid1':
# ['low1']})
def build_tree(parent=None):
children = nodes_with_children.get(parent, {})
return {node: build_tree(node) for node in children}
print build_tree()
# {
# 'top2': {
# 'mid3': {
# 'low3': {
# }
# }
# },
# 'top1': {
# 'mid2': {
# 'low2': {
# }
# },
# 'mid1': {
# 'low1': {
# }
# }
# }
# }
从集合导入defaultdict
带有子节点的节点=defaultdict(列表)
节点=['mid2','top1'],
['low2','mid2'],
['mid3','top2'],
['low1','mid1'],
['top1',无],
['top2',无],
['low3','mid3'],
['mid1','top1']]
对于节点中的子节点、父节点:
节点\u与\u子节点[parent]。追加(子节点)
打印带有子节点的节点
#defaultdict(,{'top2':['mid3'],'top1':['mid2','mid1'],
#无:['top1','top2'],'mid2':['low2'],'mid3':['low3'],'mid1':
#['low1']})
def生成树(父级=无):
children=nodes_与_children.get(父,{})
返回{node:build_tree(node)for node in children}
打印生成树()
# {
#“top2”:{
#“mid3”:{
#“低3”:{
# }
# }
# },
#“top1”:{
#“mid2”:{
#“低2”:{
# }
# },
#“mid1”:{
#“低1”:{
# }
# }
# }
# }
要获得树的深度,确实没有太多的工作要做。您可以直接在
build_tree()
中完成,这是一个有趣的问题,因此我编写了一些代码,即使您没有提供:
from collections import defaultdict
nodes_with_children = defaultdict(list)
nodes = [['mid2', 'top1'],
['low2', 'mid2'],
['mid3', 'top2'],
['low1', 'mid1'],
['top1', None],
['top2', None],
['low3', 'mid3'],
['mid1', 'top1']]
for child, parent in nodes:
nodes_with_children[parent].append(child)
print nodes_with_children
# defaultdict(<type 'list'>, {'top2': ['mid3'], 'top1': ['mid2', 'mid1'],
# None: ['top1', 'top2'], 'mid2': ['low2'], 'mid3': ['low3'], 'mid1':
# ['low1']})
def build_tree(parent=None):
children = nodes_with_children.get(parent, {})
return {node: build_tree(node) for node in children}
print build_tree()
# {
# 'top2': {
# 'mid3': {
# 'low3': {
# }
# }
# },
# 'top1': {
# 'mid2': {
# 'low2': {
# }
# },
# 'mid1': {
# 'low1': {
# }
# }
# }
# }
从集合导入defaultdict
带有子节点的节点=defaultdict(列表)
节点=['mid2','top1'],
['low2','mid2'],
['mid3','top2'],
['low1','mid1'],
['top1',无],
['top2',无],
['low3','mid3'],
['mid1','top1']]
对于节点中的子节点、父节点:
节点\u与\u子节点[parent]。追加(子节点)
打印带有子节点的节点
#defaultdict(,{'top2':['mid3'],'top1':['mid2','mid1'],
#无:['top1','top2'],'mid2':['low2'],'mid3':['low3'],'mid1':
#['low1']})
def生成树(父级=无):
children=nodes_与_children.get(父,{})
返回{node:build_tree(node)for node in children}
打印生成树()
# {
#“top2”:{
#“mid3”:{
#“低3”:{
# }
# }
# },
#“top1”:{
#“mid2”:{
#“低2”:{
# }
# },
#“mid1”:{
#“低1”:{
# }
# }
# }
# }
要获得树的深度,确实没有太多的工作要做。您可以直接在
build_tree()
中完成。我的解决方案与@Eric的非常相似,但我还是会发布它:
from collections import defaultdict
from pprint import pprint
def make_tree(name2kids, name=None):
return {kid: make_tree(name2kids, kid)
for kid in name2kids[name]}
def find_depth(tree):
if not tree:
return 0
return 1 + max(find_depth(subtree) for subtree in tree.values())
def main():
"""
>>> main()
{'top1': {'mid1': {'low1': {}}, 'mid2': {'low2': {}}},
'top2': {'mid3': {'low3': {}}}}
depth = 3
"""
nodes = [['mid2', 'top1'],
['low2', 'mid2'],
['mid3', 'top2'],
['low1', 'mid1'],
['top1', None],
['top2', None],
['low3', 'mid3'],
['mid1', 'top1']]
name2kids = defaultdict(list)
for kid, name in nodes:
name2kids[name].append(kid)
tree = make_tree(name2kids)
pprint(tree)
depth = find_depth(tree)
print('depth = {}'.format(depth))
if __name__ == '__main__':
main()
(运行:
python-m doctest script.py--verbose
)。我的解决方案与@Eric的非常相似,但我还是会发布它:
from collections import defaultdict
from pprint import pprint
def make_tree(name2kids, name=None):
return {kid: make_tree(name2kids, kid)
for kid in name2kids[name]}
def find_depth(tree):
if not tree:
return 0
return 1 + max(find_depth(subtree) for subtree in tree.values())
def main():
"""
>>> main()
{'top1': {'mid1': {'low1': {}}, 'mid2': {'low2': {}}},
'top2': {'mid3': {'low3': {}}}}
depth = 3
"""
nodes = [['mid2', 'top1'],
['low2', 'mid2'],
['mid3', 'top2'],
['low1', 'mid1'],
['top1', None],
['top2', None],
['low3', 'mid3'],
['mid1', 'top1']]
name2kids = defaultdict(list)
for kid, name in nodes:
name2kids[name].append(kid)
tree = make_tree(name2kids)
pprint(tree)
depth = find_depth(tree)
print('depth = {}'.format(depth))
if __name__ == '__main__':
main()
(运行:
python-mdoctestscript.py--verbose
)。你写了什么?你写了什么?