打印树
print-tree2的Python项目详细描述
打印目录树
这个包帮助您以一种漂亮的格式打印您的树结构。
安装
pip install print-tree2
我希望使用print_tree
作为名称,但是包已经在pypi上,尽管它不起作用。
要验证您的安装,请尝试:
git clone https://github.com/liwt31/print_tree.git
cd print_tree/
pytest
功能
github上已经有了一个漂亮的打印树库pptree,为什么要重新设计另一个轮子? 最重要的原因是:
- 此包提供不需要修改任何代码的继承接口,而pptree按设计要求节点类具有某些方法或属性。
另外,这个包裹:
不过,pptree仍然是一个很棒的包。这个实现非常漂亮,我从作者那里借鉴了一些想法。
文件
example
目录中的print*.py
文件提供了几个关于如何使用包的示例。下面可以作为这些文件的解释。example
目录中的文件启用了着色,以演示此包使用颜色打印树的能力。因为在这个md文件中看不到效果,所以会修改相应的代码。
假设我们有Node
类:
class Node(object):
def __init__(self, value, parent):
self.value = value
self.children = []
if parent is not None:
parent.children.append(self)
作为一个例子,我们构造一棵树如下:
data_structure = Node('Data Stucture', None)
vector = Node('Vector', data_structure)
list_ = Node('List', data_structure)
tree = Node('Tree', data_structure)
graph = Node('Graph', data_structure)
dag = Node('DAG', graph)
avl = Node('AVL', tree)
splay = Node('Splay', tree)
b = Node('B', tree)
quad = Node('Quand', tree)
kd = Node('kd', tree)
要打印树,我们必须告诉print_tree
两件事:
- 如何从根节点横切树。
- 如何将每个节点解释为字符串。
为了实现这些目标,我们从包中固有的print_tree
然后覆盖get_children
和get_node_str
:
from print_tree import print_tree
class print_custom_tree(print_tree):
def get_children(self, node):
return node.children
def get_node_str(self, node):
return str(node.value)
get_children
应接受一个Node
,并返回一个元素类型为Node
或PlaceHolder
的列表(有关PlaceHolder
的详细信息,请参见下文),以及get_node_str
接受一个Node
并返回一个字符串。然后我们可以像使用函数一样使用print_custom_tree
:
>>> print_custom_tree(data_structure)
┌Vector
├List
Data Stucture┤
│ ┌AVL
│ ├Splay
├Tree┼B
│ ├Quand
│ └kd
└Graph─DAG
如果对类的命名感到不舒服,可以导入PrintTree
,然后改用PrintTree
。
现在让我们来看看更复杂的例子。在example
目录中,我定义了一个带有自定义分支编号的原始搜索树。为了简洁起见,这里只显示Node
的__init__
函数。如果branch == 2
,那么它是一个二叉搜索树。
class Node(object):
def __init__(self, value, branch):
self.values = [value]
self.branch = branch
self.children = [None] * branch
如果我们想强调binary结构,我们可以重写get_children
和get_node_str
,如下所示:
class print_binary(print_tree):
def get_children(self, node):
l_child, r_child = node.children
if r_child is None and l_child is None:
return []
else:
r_child = r_child or PlaceHolder
l_child = l_child or PlaceHolder
return [r_child, l_child]
def get_node_str(self, node):
return str(node.values[0])
在这种情况下,get_children
的返回列表可能包含PlaceHolder
,可以通过from print_tree import PlaceHolder
直接导入。如果PlaceHolder
在返回列表中,则print_tree
将把它作为占位符:不显示任何内容,但需要空格:
# Tree (bst) already initialized
>>> print_binary(bst.root)
┌19┐
│ │ ┌18
│ └17┤
│ │ ┌16
│ └15┘
│
│
┌14┤
│ └13
┌12┘
│
│
11┤
│ ┌10
│ ┌9┤
│ │ └8
│ ┌7┤
│ │ │ ┌6
│ │ │ ┌5┤
│ │ │ │ │ ┌4
│ │ │ │ └3┘
│ │ │ │
│ │ └2┤
│ │ └1
└0┘
因为树是随机生成的,所以结果可能与测试安装时看到的不同。但是,在这两种情况下,您都可以将树的顺序横截面从下到上读取为list(range(20))
(0到19)。
删除后PlaceHolder
的效果变得突出(还要注意继承的好处):
class print_binary_without_placeholder(print_binary):
def get_children(self, node):
l_child, r_child = node.children
children = []
if r_child is not None:
children.append(r_child)
if l_child is not None:
children.append(l_child)
return children
# initialize the tree(bst)
...
print_binary_without_placeholder(bst.root)
┌18
┌19─17┤
│ └15─16
┌12─14┤
│ └13
11┤
│ ┌10
│ ┌9┤
│ │ └8
└0─7┤
│ ┌6
│ ┌5┤
│ │ └3─4
└2┤
└1