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

你写了什么?你写了什么?