如何使用 python anytree 获取所有可能的分支
How to get all possible branch with python anytree
我目前正在使用 anytree 生成我的搜索树,如何以列表格式从根节点开始获取所有可能的分支
from anytree import Node, RenderTree, AsciiStyle
f = Node("f")
b = Node("b", parent=f)
a = Node("a", parent=b)
d = Node("d", parent=b)
c = Node("c", parent=d)
e = Node("e", parent=d)
g = Node("g", parent=f)
i = Node("i", parent=g)
h = Node("h", parent=i)
print(RenderTree(f, style=AsciiStyle()).by_attr())
当前树:
f
|-- b
| |-- a
| +-- d
| |-- c
| +-- e
+-- g
+-- i
+-- h
想要的输出(treeBranch):
[[f,b,a], [f,b,d,c], [f,b,d,e], [f,g,i,h]]
我不确定是否有更好的方法,欢迎任何建议。
我想使用这个列表来检查树中是否存在来自用户的新路径,例如:
newPath = [f, b]
for branch in treeBranch:
if newPath in branch:
return true
else:
// add new path to tree
您想拥有每个叶节点的根路径。
只需使用 PreOrderIter 和 filter_
来检索叶节点:
print(list(PreOrderIter(f, filter_=lambda node: node.is_leaf)))
[a, c, e, h]
然后访问每个节点上的path attribute:
print([list(leaf.path) for leaf in PreOrderIter(f, filter_=lambda node: node.is_leaf)])
[[f,b,a], [f,b,d,c], [f,b,d,e], [f,g,i,h]]
如果您希望从树中的任何节点到叶节点的路径:
def allpaths(start):
skip = len(start.path) - 1
return [leaf.path[skip:] for leaf in PreOrderIter(start, filter_=lambda node: node.is_leaf)]
print(allpaths(b))
[(b, a), (b, d, c), (b, d, e)]
请注意,还有一个 Walker,它提供从任何节点到另一个节点的路径。
@c0fec0de 的解决方案在 anytree 2.8.0 中似乎不再适用。我尝试了以下方法:
from anytree import Node, RenderTree, AsciiStyle, PreOrderIter
f = Node("f")
b = Node("b", parent=f)
a = Node("a", parent=b)
d = Node("d", parent=b)
c = Node("c", parent=d)
e = Node("e", parent=d)
g = Node("g", parent=f)
i = Node("i", parent=g)
h = Node("h", parent=i)
print(RenderTree(f, style=AsciiStyle()).by_attr())
它给了我下面的树:
f
|-- b
| |-- a
| +-- d
| |-- c
| +-- e
+-- g
+-- i
+-- h
在此之后,为了获取树中所有分支的列表,我尝试了:
>>> print(list(PreOrderIter(f, filter_=lambda node: node.is_leaf)))
[Node('/f/b/a'), Node('/f/b/d/c'), Node('/f/b/d/e'), Node('/f/g/i/h')]
由于响应在节点对象中,为了将其转换为字符串形式的节点列表,我执行了以下操作:
>>> lst = list(PreOrderIter(f, filter_=lambda node: node.is_leaf))
>>> print(lst)
[Node('/f/b/a'), Node('/f/b/d/c'), Node('/f/b/d/e'), Node('/f/g/i/h')]
>>> f = [str(i)[7:-2].split(i.separator) for i in lst]
>>> print(f)
[['f', 'b', 'a'], ['f', 'b', 'd', 'c'], ['f', 'b', 'd', 'e'], ['f', 'g', 'i', 'h']]
很想知道是否有更好的方法来做同样的事情。
@michael-westen 我完全利用 .name 和 .path 并避免字符串操作的解决方案:
leaves = [node_i.name for node_i in PreOrderIter(f.root, filter_=lambda node: node.is_leaf)]
branches = [[node_i.name for node_i in data_i.path] for data_i in PreOrderIter(f.root, filter_=lambda node: node.is_leaf)]
我目前正在使用 anytree 生成我的搜索树,如何以列表格式从根节点开始获取所有可能的分支
from anytree import Node, RenderTree, AsciiStyle
f = Node("f")
b = Node("b", parent=f)
a = Node("a", parent=b)
d = Node("d", parent=b)
c = Node("c", parent=d)
e = Node("e", parent=d)
g = Node("g", parent=f)
i = Node("i", parent=g)
h = Node("h", parent=i)
print(RenderTree(f, style=AsciiStyle()).by_attr())
当前树:
f
|-- b
| |-- a
| +-- d
| |-- c
| +-- e
+-- g
+-- i
+-- h
想要的输出(treeBranch):
[[f,b,a], [f,b,d,c], [f,b,d,e], [f,g,i,h]]
我不确定是否有更好的方法,欢迎任何建议。
我想使用这个列表来检查树中是否存在来自用户的新路径,例如:
newPath = [f, b]
for branch in treeBranch:
if newPath in branch:
return true
else:
// add new path to tree
您想拥有每个叶节点的根路径。
只需使用 PreOrderIter 和 filter_
来检索叶节点:
print(list(PreOrderIter(f, filter_=lambda node: node.is_leaf)))
[a, c, e, h]
然后访问每个节点上的path attribute:
print([list(leaf.path) for leaf in PreOrderIter(f, filter_=lambda node: node.is_leaf)])
[[f,b,a], [f,b,d,c], [f,b,d,e], [f,g,i,h]]
如果您希望从树中的任何节点到叶节点的路径:
def allpaths(start):
skip = len(start.path) - 1
return [leaf.path[skip:] for leaf in PreOrderIter(start, filter_=lambda node: node.is_leaf)]
print(allpaths(b))
[(b, a), (b, d, c), (b, d, e)]
请注意,还有一个 Walker,它提供从任何节点到另一个节点的路径。
@c0fec0de 的解决方案在 anytree 2.8.0 中似乎不再适用。我尝试了以下方法:
from anytree import Node, RenderTree, AsciiStyle, PreOrderIter
f = Node("f")
b = Node("b", parent=f)
a = Node("a", parent=b)
d = Node("d", parent=b)
c = Node("c", parent=d)
e = Node("e", parent=d)
g = Node("g", parent=f)
i = Node("i", parent=g)
h = Node("h", parent=i)
print(RenderTree(f, style=AsciiStyle()).by_attr())
它给了我下面的树:
f
|-- b
| |-- a
| +-- d
| |-- c
| +-- e
+-- g
+-- i
+-- h
在此之后,为了获取树中所有分支的列表,我尝试了:
>>> print(list(PreOrderIter(f, filter_=lambda node: node.is_leaf)))
[Node('/f/b/a'), Node('/f/b/d/c'), Node('/f/b/d/e'), Node('/f/g/i/h')]
由于响应在节点对象中,为了将其转换为字符串形式的节点列表,我执行了以下操作:
>>> lst = list(PreOrderIter(f, filter_=lambda node: node.is_leaf))
>>> print(lst)
[Node('/f/b/a'), Node('/f/b/d/c'), Node('/f/b/d/e'), Node('/f/g/i/h')]
>>> f = [str(i)[7:-2].split(i.separator) for i in lst]
>>> print(f)
[['f', 'b', 'a'], ['f', 'b', 'd', 'c'], ['f', 'b', 'd', 'e'], ['f', 'g', 'i', 'h']]
很想知道是否有更好的方法来做同样的事情。
@michael-westen 我完全利用 .name 和 .path 并避免字符串操作的解决方案:
leaves = [node_i.name for node_i in PreOrderIter(f.root, filter_=lambda node: node.is_leaf)]
branches = [[node_i.name for node_i in data_i.path] for data_i in PreOrderIter(f.root, filter_=lambda node: node.is_leaf)]