【问题标题】:Generic Tree in Recursion in PythonPython中递归中的泛型树
【发布时间】:2018-06-22 22:19:42
【问题描述】:

我是 Python 的新手,陷入了通用树中。

我有 2 列。假设名称为 A 和 B。现在问题是 A 列的值是 B 列中相应值的父项。现在 B 列的值再次在 A 列中搜索。现在它成为父项,其对应值是子项.

例如:

A    B
--------
1    2
5    3
2    5
3    

现在这里是值“1”。

1 是父级。 2 是 1 的孩子。现在在 A 列中再次搜索 2。这现在使 2 成为父母,5 成为其孩子。现在我们再次搜索它给了我们 Value 3 。 3 也是如此,但 3 前面没有值,所以树在这里结束,3 是树的叶节点。在此示例中,我显示了每个父节点的一个子节点,但在我的数据集中,每个父节点可以有多个子节点,并且树会一直运行,直到到达所有叶节点。我知道递归是这里的解决方案,但是如何?

我在输出中需要的是与父级的所有可能集合。在这种情况下,[1,2]、[1,2,5]、[1,2,5,3]。此外,如果 1 有 2 个孩子,假设 2 和 4。

那么[1,2,4]也会被算作一个集合。这里有什么帮助吗?我真的很努力!

Venky = {}

def Venkat(uno):
    x = df[df.ColA == uno]
    data = list(zip(x['ColB'],x.ColA))
    Venky[uno] = Node(uno)

    for child,parent in data:
        Venky[child] = Node(child, parent=Venky[uno])
        print(Venky[child])
        y = df[df['ColA'] == (Venky[child]).name]
        if (y['ColB'].empty == False):
            data = list(zip(y['ColB'],y.ColA,))
            #y_unique = y['ColB'].unique()
            for k in y['ColB']:
                    
                    res = Venkat(k)
                    return res
        
        
udo = 'a'
Venkat(udo)
for pre, fill, node in RenderTree(Venky[udo]):
    print("%s%s" % (pre, node.name))

以上是我的示例代码。 df 是我的 colA 和 colB 数据框。 ColA 是 A 列,与 colB 相同。我还为此代码导入了 Anytree 和 pandas 库。我得到的结果是这样的:

Node('/1/2')
Node('/4/nan')
1
└── 2
Node('/1/2')
Node('/4/nan')
None

这里 4 是树中 2 的兄弟,即 1 在这里有 2 个孩子 2 和 4 与数据集不同。但目前我不关心输出。我现在想构建一棵树。然后我会玩弄输出。

【问题讨论】:

  • 是的,我知道,但不知道从哪里开始。
  • 感谢您的指出,但下次一定会注意的。
  • 我已经更新了我上面的问题,相信我已经在这里搜索了所有可能的 python 树链接

标签: python recursion tree


【解决方案1】:

我建议您首先将表结构转换为字典,为每个节点(字典键)提供子节点(字典值)列表。

然后执行深度优先遍历该树,使用递归,用新访问的子节点扩展路径。输出每个阶段的路径。为此,生成器是一个理想的解决方案。

代码:

def all_paths(table, root):
    # convert table structure to adjacency list
    children = {}
    for node, child in table:
        if child: 
            children[node] = children.setdefault(node, []) + [child]

    # generator for iteration over all paths from a certain node
    def recurse(path):
        yield path
        if path[-1] in children:
            for child in children[path[-1]]: # recursive calls for all child nodes
                yield from recurse(path + [child])

    return recurse([root])

# Sample data in simple list format    
table = [
    [1, 2],
    [5, 3],
    [2, 5],
    [2, 6],
    [2, 4],
    [6, 7],
]

# Output all paths from node 1
for path in all_paths(table, 1):
    print(path)

以上输出:

[1]
[1, 2]
[1, 2, 5]
[1, 2, 5, 3]
[1, 2, 6]
[1, 2, 6, 7]
[1, 2, 4]

看到它在repl.it上运行

【讨论】:

  • 感谢@trincot 的精彩回复。对此,我真的非常感激。该代码运行良好,但它只打印 1 的子代,而不是其子代的其他子代。我希望填充整棵树。再次感谢
  • 不确定你的意思。查看在repl.it 上生成的输出。注意:yield from 语法需要 python 3.3+。
  • 是的,它在 repl.it 上运行良好。但是在我的数据集中,当 ColB 中没有相应的值(Na)时,树就结束了。可能这会导致我的数据框出现错误
  • 我的坏。它完全解决了我的问题。感谢这个优雅而甜蜜的代码。
  • 顺便说一句,有什么办法可以渲染一棵树吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-09
  • 2022-01-19
  • 1970-01-01
  • 2013-03-09
  • 1970-01-01
  • 1970-01-01
  • 2012-07-03
相关资源
最近更新 更多