Python 从具有重复子树的嵌套列表构造树视图(使用anytree/treelib)
我有一个嵌套列表,如下所示:Python 从具有重复子树的嵌套列表构造树视图(使用anytree/treelib),python,python-3.x,tree,treeview,anytree,Python,Python 3.x,Tree,Treeview,Anytree,我有一个嵌套列表,如下所示: lst = [['a', 'b', 'e'], # this e is the branch of b ['a', 'f', 'e'], # this e is the branch of f, ['a', 'h', 'i i i']] # string with spaces 我想建造一棵树,就像: a ├── b │ └── e ├── f | └── e └── h └── i i i 我想
lst = [['a', 'b', 'e'], # this e is the branch of b
['a', 'f', 'e'], # this e is the branch of f,
['a', 'h', 'i i i']] # string with spaces
我想建造一棵树,就像:
a
├── b
│ └── e
├── f
| └── e
└── h
└── i i i
我想使用两个包中的任何一个:和。我读过很多帖子,尝试过很多不同的方法,但都没有成功
更新:
我想出了以下方法,但我现在遇到的问题是
from anytree import Node, RenderTree
lst = [["a", "b", "c", "e"], ["a", "b", "f"], ["a", "b", "c", "g", "h"], ["a", "i"]]
def list_to_anytree(lst):
root_name = lst[0][0]
root_node = Node(root_name)
nodes = {root_name: root_node} # keeping a dict of the nodes
for branch in lst:
assert branch[0] == root_name
for parent_name, node_name in zip(branch, branch[1:]):
node = nodes.setdefault(node_name, Node(node_name))
parent_node = nodes[parent_name]
if node.parent is not None:
assert node.parent.name == parent_name
else:
node.parent = parent_node
return root_node
anytree = list_to_anytree(lst)
for pre, fill, node in RenderTree(anytree):
print(f"{pre}{node.name}")
这里发生的事情不多。我只是将列表转换为任意树节点(执行此操作时,列表表示是有效的)。我在节点中保留了一个节点字典
产出确实很高
a
├── b
│ ├── c
│ │ ├── e
│ │ └── g
│ │ └── h
│ └── f
└── i
如果您有多个同名节点,则不能使用上面的dict
;您需要从根节点迭代子节点:
def list_to_anytree(lst):
root_name = lst[0][0]
root_node = Node(root_name)
for branch in lst:
parent_node = root_node
assert branch[0] == parent_node.name
for cur_node_name in branch[1:]:
cur_node = next(
(node for node in parent_node.children if node.name == cur_node_name),
None,
)
if cur_node is None:
cur_node = Node(cur_node_name, parent=parent_node)
parent_node = cur_node
return root_node
你的榜样
lst = [
["a", "b", "e"], # this e is the branch of b
["a", "f", "e"], # this e is the branch of f,
["a", "h", "i i i"],
]
anytree = list_to_anytree(lst)
for pre, fill, node in RenderTree(anytree):
print(f"{pre}{node.name}")
然后给出:
a
├── b
│ └── e
├── f
│ └── e
└── h
└── i i i
嗨,伙计。由于某些原因,我不断得到一个带有空格字符串的AssertError。你能看看我最新的问题吗?嗨,史蒂文!问题不在于具有空格的节点,而是有两个名为e
的节点具有不同的父节点。如果不需要考虑这一点,我需要稍微更改一下逻辑(我的节点
字典将无法工作…)。嗨,伙计。有没有其他方法可以使用next()来缩短代码?据我所知,没有。。。例如,请参见以下内容:。您可以将其打包到一个函数中(将其分解):def next\u child(cur\u node\u name,parent\u node):return next(…)
a
├── b
│ └── e
├── f
│ └── e
└── h
└── i i i