我有如下数据集:
A B
1 2
5 3
2 5
3
下面的代码给出了以下输出:
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)
Output:
[1]
[1, 2]
[1, 2, 5]
[1, 2, 5, 3]
[1, 2, 6]
[1, 2, 6, 7]
[1, 2, 4]
但我想要的是以渲染树格式打印输出,如下所示:
1
└── 2
|── 5
| └──3
|── 6
| └──7
└── 4
我知道python库Anytree在这里很有用,但我不知道如何实现这段代码。任何帮助都将受到高度赞赏。
答案 0 :(得分:0)
您当前的输出# to fold a tree you need first to get the leave for each flattened branch at proper levels
# toleavel([1,2,5]) --> [[[5]]]
def toleave(branch):
if branch[1:] == []:
return [branch[0]]
else:
return [toleave(branch[1:])]
# fold the flattened tree
def fold(flattened_tree):
if flattened_tree == []:
return []
else:
return toleave(flattened_tree[0]) + fold(flattened_tree[1:])
# decorator for rendering
def render(f):
render.level = -2
indent = ' '
def _f(*args):
render.level += 1
try:
result = f(*args)
if not isinstance(result, list):
print(render.level*indent, result)
finally:
render.level = -2
return result
return _f
# go over a tree and render it
@render
def tree_render(tree):
if not isinstance(tree, list):
return tree
elif tree == []:
return []
else:
return [tree_render(tree[0])] + [tree_render(tree[1:])]
flattened_tree = [[1], [1, 2], [1, 2, 5], [1, 2, 5, 3], [1, 2, 6], [1, 2, 6, 7], [1, 2, 4]]
tree_render(fold(flattened_tree))
# output:
# 1
# 2
# 5
# 3
# 6
# 7
# 4
是一个展平列表。第一步是将其折叠成树形结构。然后你可以通过一个简单的装饰器渲染它。 (下面的代码用Python 3.6.1测试)
{{1}}
答案 1 :(得分:0)
使用字典(如果需要collections.OrderedDict
)将使循环更容易。
使用推荐的anytree
包,它将提供所需的图形输出,整个代码将只是:
import anytree
# parent-child relations
table = [
[1, 2],
[5, 3],
[2, 5],
[2, 6],
[2, 4],
[6, 7],
]
def build_tree_recursively(p_num, p_node):
for c_num in parent_children[p_num]: # add children
c_node = anytree.Node(str(c_num), parent=p_node)
if c_num in parent_children: # dive into
build_tree_recursively(c_num, c_node)
# map parents to list of children
parent_children = {}
for p, c in table: # numbers
if p in parent_children:
parent_children[p].append(c)
else:
parent_children[p] = [c]
p = 1 # assuming single root node (else add loop over elements not in column B)
tree = anytree.Node(str(p))
build_tree_recursively(p, tree)
# render
for pre, fill, node in anytree.RenderTree(tree):
print("{}{}".format(pre, node.name))