【问题标题】:Recursive function for trees in PythonPython中树的递归函数
【发布时间】:2013-03-09 15:03:28
【问题描述】:

我正在尝试在 Python 中创建一个函数,它采用树的任意节点,并根据节点给定填充列表列表。

鉴于以下绘制得很糟糕的树:

如果我们从节点 5 开始,我们应该得到:

  • 包含具有相同父节点的所有节点的列表,包括我们从(4 和 5)开始的那个
  • 任何子节点,但不是它们的子节点 (6)。
  • 父节点和具有相同父节点的任何父节点,以及它们的父节点等,直到我们到达根节点,但不包括根节点(在这种情况下只有 2 和 3,但如果树更深我们从较低的起点开始,这里会更多。

并且节点应该以列表列表的形式结束,每个深度一个列表。

python中的节点:

nodes = [
    {'id': 1, 'parent': None},
    {'id': 2, 'parent': 1},
    {'id': 3, 'parent': 1},
    {'id': 4, 'parent': 2},
    {'id': 5, 'parent': 2},
    {'id': 6, 'parent': 5},
    {'id': 7, 'parent': 6},
    {'id': 8, 'parent': 3}
]

我们只能看到父母,不能看到孩子,但遗憾的是,这是我必须使用的数据格式。

因此,如果我们采用节点 5,我们希望最终得到一个看起来像这样的节点列表:

nl = [
    [{'id': 6, 'parent': 5}],
    [{'id': 4, 'parent': 2}, {'id': 5, 'parent': 2}],
    [{'id': 2, 'parent': 1}, {'id': 3, 'parent': 1}],
]

这是我到目前为止的代码。我认为递归函数可能是最简单的方法。不幸的是,它似乎并没有像我认为的那样做,而且显然我做错了什么。而且这段代码甚至没有考虑获取我根本不完全确定如何处理的子节点,除了可能会更容易处理之后。

node_list = []

def pop_list(nodes=None, parent=None, node_list=None):
    if parent is None:
        return node_list
    node_list.append([])
    for node in nodes:
        if node['parent'] == parent:
            node_list[-1].append(node)
        if node['id'] == parent:
            parent = node['parent']
    return pop_list(nodes, parent, node_list)

print pop_list(nodes, 5, node_list)

这是输出:

[[], [{'id': 3, 'parent': 1}], []]

不完全确定我在哪里出错了。

【问题讨论】:

  • 对此有所了解,但想确保我理解...您想要三个单独的列表,嵌套在一个主列表中,每个列表都按照项目符号列表中的说明进行填充?
  • 不完全。对于这个例子,有。但是如果树更深,就会有更多的列表。如果我们开始更浅,更少。基本上每个深度都有一个列表。
  • 澄清一下,如果我们从节点 7 开始,将会有一个 7 的列表、一个 6 的列表、一个 4,5 的列表和一个 2,3 的列表

标签: python recursion tree


【解决方案1】:
def processNode(bp, space=''):
    if ('name' in bp[0].keys() ):
        print( space + bp[0]['name'])
    if ('subNodesTitle' in bp[0].keys()):
        print( bp[0]['subNodesTitle'])
        processNode( bp[0]['subNodes'],space=space+' ')
    if (len(bp) > 1):
        processNode( bp[1:],space=space )
processNode(root)

这个函数可以通过一个不平衡的树进行递归,

【讨论】:

    【解决方案2】:

    问题来了

        if node['id'] == parent:
            parent = node['parent']
    

    当前parent 将被其父级覆盖。

    此外,您应该在函数末尾添加return node_list,或者使用node_list作为结果。

    def pop_list(nodes=None, parent=None, node_list=None):
        if parent is None:
            return node_list
        node_list.append([])
        for node in nodes:
            if node['parent'] == parent:
                node_list[-1].append(node)
            if node['id'] == parent:
                next_parent = node['parent']
    
        pop_list(nodes, next_parent, node_list)
        return node_list
    
    >>> print pop_list(nodes, 5, node_list)
    [[{'id': 6, 'parent': 5}], [{'id': 4, 'parent': 2}, {'id': 5, 'parent': 2}], [{'id': 2, 'parent': 1}, {'id': 3, 'parent': 1}]]  
    

    【讨论】:

    • 啊,菜鸟的错误。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-03-13
    • 2020-05-30
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    相关资源
    最近更新 更多