简体   繁体   English

Python中树的递归函数

[英]Recursive function for trees in Python

I'm trying to make a function in Python, that takes an arbitrary node of a tree, and populates a list of lists based on the node give.我正在尝试在 Python 中创建一个函数,该函数采用树的任意节点,并根据节点给出的列表填充列表。

Given the following badly drawn tree:鉴于以下绘制错误的树:

树

If we start at, for example, node 5, we should get:例如,如果我们从节点 5 开始,我们应该得到:

  • A list containing all nodes with the same parent node, including the one we started at (4 and 5)包含具有相同父节点的所有节点的列表,包括我们从(4 和 5)开始的节点
  • Any child nodes, but not their children (6).任何子节点,但不是它们的子节点 (6)。
  • Parent nodes and any parent nodes with the same parent, and their parent's nodes, etc. until we get to the root node, but not including the root node (just 2 and 3 in this case, but if the tree was deeper and we started lower, there'd be more here.父节点和任何具有相同父节点的父节点,以及它们的父节点等,直到我们到达根节点,但不包括根节点(在这种情况下只有 2 和 3,但如果树更深,我们开始更低,这里会有更多。

And the nodes should end up in a list of lists, one list for each depth.并且节点应该在一个列表列表中结束,每个深度一个列表。

The nodes in python: 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}
]

We can only see parents, not children, but this is the data format I have to work with, sadly.我们只能看到父母,不能看到孩子,但遗憾的是,这是我必须使用的数据格式。

So from this, if we take node 5, we want to end up with a node list looking something like this:因此,如果我们采用节点 5,我们希望最终得到一个看起来像这样的节点列表:

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

This is the code I have so far.这是我到目前为止的代码。 I figure a recursive function is probably the simplest way.我认为递归函数可能是最简单的方法。 Unfortunately it seems to do nothing like what I think it should, and obviously I'm doing something very wrong.不幸的是,它似乎没有像我认为的那样做,显然我做错了。 And this code doesn't even consider geting the child nodes which I'm not entirely sure how to deal with at all, apart from possibly handing the afterwards which would be much easier.并且这段代码甚至没有考虑获取我根本不完全确定如何处理的子节点,除了可能处理之后会容易得多。

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)

Here is the output:这是输出:

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

Not exactly sure where I'm going wrong here.不完全确定我哪里出错了。

The problem is here问题就在这里

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

The current parent will be overwritten by its parent.当前parent将被parent覆盖。

Moreover, you should add return node_list at the end of the function, or use node_list as results.此外,您应该在函数末尾添加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}]]  
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)

This function can recurse through an unbalanced tree,这个函数可以通过一个不平衡的树递归,

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

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