假设我有一个 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]and[e, f]和[g]。但是现在,元素[d, e, f, g]不同了,[a, b, c]因为它里面有 2 个不同的子分支而不是一个。所以,像这样的树:
l1
|
|_a
| |__b
| |__c
|
|_d
|__e
| |__f
|__g
会被描述为:
编辑:修复了输入树,因为f没有独立的分支
l1=[
[a,b,c],
[b, c],
[c],
[d,e,f,g],
[e,f]
[f]
[g]
]