在Python中渲染一棵树

2024-04-28 15:20:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有如下数据集:

A    B

1    2
5    3
2    5
3    

下面的代码给出了以下输出:

^{pr2}$

但我想在这里打印输出的渲染树格式如下:

1
└── 2
    |── 5
    |   └──3 
    |── 6
    |   └──7
    └── 4

我知道python库Anytree在这里很有用,但我不知道如何实现这段代码。任何帮助都将不胜感激。在


Tags: 数据代码格式anytree打印输出pr2
2条回答

您当前的输出[[1], [1, 2], [1, 2, 5], [1, 2, 5, 3], [1, 2, 6], [1, 2, 6, 7], [1, 2, 4]]是一个扁平化列表。第一步是把它折叠成树状结构。然后你可以通过一个简单的装饰器来渲染它。(下面的代码是用python3.6.1测试的)

# 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

使用字典(如果需要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))

相关问题 更多 >