【发布时间】:2019-09-22 05:13:43
【问题描述】:
假设我有一个如下所示的 Python 3.6 列表:
l1 = [
[a,b,c],
[b,c],
[c],
[d, e],
[e]
...
]
我需要使用anytree 将其转换为树状结构,使其看起来像这样:
>>> print(RenderTree(l1))
l1
|__ a
| |__b
| |__c
|___d
|__e
如果有任何帮助,请将对象 a、b、c、d、e 视为字符串。我目前已经阅读了很多关于 anytree 的文档,并在 StackOverflow 上搜索了一段时间,但找不到任何可以帮助我解决这个问题的东西。我可以解决这个问题的最 Pythonic 方式是什么?
编辑:澄清一下,原始列表l1 应该代表一棵树,其中l1 中的第一个元素是父节点,其中的每个节点都是一个子节点。每个子节点都可以是前一个节点的子节点,以此类推
编辑编辑:所以,原始列表(假设)如下所示:
l1 = [
['a', 'b', 'c'],
['b', 'c'],
['c'],
['d', 'e'],
['e']
]
在这里,每个子列表的第一个元素总是最终成为该分支的父元素。将这些分支中的每一个连接在一起将使我获得所需的格式,但我一直在努力将其表达出来(现在是凌晨 2 点)。以下是我的一些尝试:
用于将列表转换为节点:
from anytree import Node
l = []
for x in l1:
a = Node(x[0])
for i in x[1:]:
Node(i, parent = a)
l.append(a)
但是,这会返回一个树/列表:
>>> l
[Node('/a'), Node('/b'), Node('/c'), Node('/d'), Node('/e')]
>>> print(RenderTree(l[0]))
Node('/a')
├── Node('/a/b')
└── Node('/a/c')
>>> print(RenderTree(l[1]))
Node('/b')
└── Node('/b/c')
>>> print(RenderTree(l[2]))
Node('/c')
>>> print(RenderTree(l[3]))
Node('/d')
└── Node('/d/e')
>>> print(RenderTree(l[4]))
Node('/e')
为了过滤掉这个,我尝试了以下操作:
def tuple_replace(tup, pos, val):
return tup[:pos] + (val,) + tup[pos+1:]
>>> l2=[]
>>> for pos, x in enumerate(l):
for pos_2, i in enumerate(x.children):
for j in l[pos+1:]:
if j.name == i.name:
x.children = tuple_replace(x.children, pos_2, i)
break
l2.append(x)
>>> for x in l2:
print(RenderTree(x))
Node('/a')
├── Node('/a/b')
└── Node('/a/c')
Node('/a')
├── Node('/a/b')
└── Node('/a/c')
Node('/b')
└── Node('/b/c')
Node('/d')
└── Node('/d/e')
这就是我目前的步骤
编辑编辑编辑:
所以,树的表示方式是我有一个函数,它返回一个类似l1 的列表,其背后有以下逻辑:
列表中的每个元素都有 2 个部分。家长,还有孩子。父元素是列表中的第一个元素,其他所有元素都是它的子元素,或者是子元素的子元素,依此类推。所以像:[a, b, c] 和 [d, e, f, g] 这样的元素代表分支中的所有元素,而不仅仅是持续下降的直接父级。这就是其他元素发挥作用的地方。下一个元素通常包含父元素的第一个子元素:[b, c] 和 [e, f] 和 [g]。但是现在,元素[d, e, f, g] 与[a, b, c] 不同,因为它内部有2 个不同的子分支,而不是1 个。所以,像这样的一棵树:
l1
|
|_a
| |__b
| |__c
|
|_d
|__e
| |__f
|__g
将被描述为:
编辑:修复了输入树,因为 f 没有独立分支
l1=[
[a,b,c],
[b, c],
[c],
[d,e,f,g],
[e,f]
[f]
[g]
]
【问题讨论】:
-
您可以将您的代码发布为minimal reproducible example吗?
-
我该怎么做?问题是我的问题也很抽象。可能还有其他一些隐含的条件,我稍后会补充
-
SO 不是免费的编码、设计或研究服务。如果某些东西过于抽象,那意味着你需要做更多的研究。转储要求不是获得答案的好方法。
-
嗯,我绝对同意你@MadPhysicist。我对在 StackOverflow 上发布问题还很陌生。你建议我如何详细说明这个问题?
-
您可以导入库并尝试将列表组织成库接受的格式。从文档看来,它使用了
marc = Node("Marc", parent=udo)格式。即使在解释之后,我也不清楚l1如何代表一棵树。你能用图表阐明实际结构吗?谢谢。