Python树结构库Treelib实战指南
文章目录
树结构是一种常见且重要的数据结构。Python中的treelib库是对树结构的有效实现。在 treelib 库中,实现了两个类 Tree
和 Node
,分别用于创建多叉树和创建节点。
一、安装
pip install treelib
二、基本用法
2.1 创建多叉树
from treelib import Tree, Node
# 创建一棵多叉树
tree = Tree()
Tree 类用于实例化一棵多叉树。有四个初始化参数:Tree(tree=None, deep=False, node_class=None, identifier=None),都有默认值。函数定义如下:
def __init__(self, tree=None, deep=False, node_class=None, identifier=None):
2.2 添加节点
创建完多叉树后,我们可以基于tree.create_node()函数来添加节点。
# 添加节点
tree.create_node('Harry', 'harry') # 根节点
tree.create_node('Jane', 'jane', parent='harry')
tree.create_node('Bill', 'bill', parent='harry')
tree.create_node('Diane', 'diane', parent='jane')
tree.create_node('Mary', 'mary', parent='diane')
tree.create_node('Mark', 'mark', parent='jane')
create_node(tag=None, identifier=None, parent=None, data=None): 创建一个节点并直接添加到树中。函数定义如下:
def create_node(self, tag=None, identifier=None, parent=None, data=None):
"""
Create a child node for given @parent node. If ``identifier`` is absent,
a UUID will be generated automatically.
"""
add_node(node, parent=None): 添加一个节点到树中。这个方法需要先用 Node 类创建好节点,第一个参数传入节点,第二参数同create_node()方法。
def add_node(self, node, parent=None):
"""
Add a new node object to the tree and make the parent as the root by default.
The 'node' parameter refers to an instance of Class::Node.
"""
2.2 输出树结构
tree.show()
这你,如果 tree.show()显示很多符号,而不是教程中所给的树结构时,可以使用
tree.show(line_type='ascii')
。
print(tree)
输出如下:
Harry
├── Bill
└── Jane
├── Diane
│ └── Mary
└── Mark
2.3 返回多叉树中的节点
2.3.1 tree.all_nodes()
all_nodes(): 返回多叉树中的所有节点,返回结果是一个节点对象构成的列表,节点的顺序是添加到树中的顺序。
print(tree.all_nodes()) # 返回多叉树中的节点
输出:
[Node(tag=Harry, identifier=harry, data=None), Node(tag=Jane, identifier=jane, data=None), Node(tag=Bill, identifier=bill, data=None), Node(tag=Diane, identifier=diane, data=None), Node(tag=Mary, identifier=mary, data=None), Node(tag=Mark, identifier=mark, data=None)]
直接打印节点,会将节点作为一个类对象打印出来。节点的tag、identifier和data三条属性可以单独调用,可以看到在不指定值时,tag与identifier相等,是一个系统分配的唯一值。
2.3.2 tree.all_nodes_itr()
all_nodes_itr(): 返回多叉树中的所有节点,返回结果是一个迭代器,节点的顺序是添加到树中的顺序。
for node in tree.all_nodes_itr():
print(node)
输出:
Node(tag=Harry, identifier=harry, data=None)
Node(tag=Jane, identifier=jane, data=None)
Node(tag=Bill, identifier=bill, data=None)
Node(tag=Diane, identifier=diane, data=None)
Node(tag=Mary, identifier=mary, data=None)
Node(tag=Mark, identifier=mark, data=None)
2.3.3 tree.expand_tree()
expand_tree(): 返回多叉树中的所有节点id,返回结果是一个生成器,顺序是按深度优先遍历的顺序。可以传入过滤条件等参数来改变返回的生成器。
for id in tree.expand_tree():
print(id)
输出:
harry
bill
jane
diane
mary
mark
2.4 判断是否为根/叶子节点
for node in tree.all_nodes_itr():
print(node)
print('leaf:', node.is_leaf())
print('root:', node.is_root())
输出:
Node(tag=Harry, identifier=harry, data=None)
leaf: False
root: True
Node(tag=Jane, identifier=jane, data=None)
leaf: False
root: False
Node(tag=Bill, identifier=bill, data=None)
leaf: True
root: False
Node(tag=Diane, identifier=diane, data=None)
leaf: False
root: False
Node(tag=Mary, identifier=mary, data=None)
leaf: True
root: False
Node(tag=Mark, identifier=mark, data=None)
leaf: True
root: False
2.5 多叉树的深度和叶子节点
2.5.1 多叉树的深度
print('tree depth:', tree.depth())
输出:
tree depth: 3
2.5.2 树的叶子节点
print('tree leaves:', tree.leaves())
输出:
tree leaves: [Node(tag=Bill, identifier=bill, data=None), Node(tag=Mary, identifier=mary, data=None), Node(tag=Mark, identifier=mark, data=None)]
2.5.3 到叶子节点的路径
print(tree.paths_to_leaves())
输出:
[['harry', 'bill'], ['harry', 'jane', 'diane', 'mary'], ['harry', 'jane', 'mark']]
2.6 其他用法
children(nid): 传入节点id,返回节点的所有子节点,返回结果是一个节点列表,如果没有子节点则返回空列表。
is_branch(nid): 传入节点id,返回节点的所有子节点id,返回结果是一个列表,如果没有子节点则返回空列表。
siblings(nid): 传入节点id,返回节点的所有兄弟节点,返回结果是一个节点列表,如果没有兄弟节点则返回空列表。
parent(nid): 传入节点id,返回节点的父节点,如果传入的是根节点,则返回None。
ancestor(nid, level=None): 传入节点id,返回节点的一个祖先节点,如果指定level则返回level层的祖先节点,如果不指定level则返回父节点,如果指定level比节点的层数大,则报错。
is_ancestor(ancestor, grandchild): 传入两个节点id,判断ancestor是不是grandchild的祖先,返回布尔值。
rsearch(nid, filter=None): 传入节点id,遍历节点到根节点的路径上的所有节点id,包含该节点和根节点,返回结果是一个生成器。可以传入过滤条件对结果进行过滤。
三、高级用法
参考文献
作者:酒酿小圆子~