Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中树的递归函数_Python_Recursion_Tree - Fatal编程技术网

Python中树的递归函数

Python中树的递归函数,python,recursion,tree,Python,Recursion,Tree,我正在尝试用Python制作一个函数,它获取树的任意节点,并根据给定的节点填充列表列表 考虑到以下绘制糟糕的树: 例如,如果我们从节点5开始,我们应该得到: 包含具有相同父节点的所有节点的列表,包括我们从(4和5)开始的节点 任何子节点,但不是其子节点(6) 父节点和具有相同父节点的任何父节点,以及它们的父节点,等等,直到我们到达根节点,但不包括根节点(在本例中仅为2和3,但如果树更深,并且我们从更低的位置开始,这里会有更多 节点应该以列表的形式结束,每个深度对应一个列表 python中的

我正在尝试用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}],
]

这是我至今为止的代码。我认为递归函数可能是最简单的方法。不幸的是,它似乎并没有像我所想的那样做,而且显然我做了一些非常错误的事情。而且,这个代码甚至没有考虑到那些我不完全确定如何处理的子节点,除了可能的处理。e之后,这会容易得多

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}], []]
我不太清楚我哪里出了问题。

问题就在这里

    if node['id'] == parent:
        parent = node['parent']
当前的
父项
将被其父项覆盖

此外,您应该在函数末尾添加
返回节点列表
,或者使用
节点列表
作为结果

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}]]  

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

有一个漏洞,但我想确保我理解…你想要三个独立的列表,嵌套在一个主列表中,每个列表都按照项目符号列表中的描述填充?不完全是。在这个例子中有。但是如果树更深,列表会更多。如果我们开始mo,列表会更少我们很浅。基本上每个深度都有一个列表。为了澄清,如果我们从节点7开始,会有一个7的列表,一个6的列表,一个4,5的列表,还有一个2,3Ah的列表,一个新手错误。谢谢!
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)