树,对于计算机编程语言来说是一个重要的数据结构。它具有广泛的应用,比如文件系统的分层数据结构和机器学习中的一些算法。这里创建了treelib来提供Python中树数据结构的高效实现。

官方文档:https://treelib.readthedocs.io/en/latest/

1.安装
主要通过pip和easy_install进行安装

windows下:pip install treelib

Linux下:sudo easy_install -U treelib


License许可:

Redistributed under Apache License (2.0) since version 1.3.0.

2.类定义
主要分为Tree和Node两个类,以支持多叉树的实现

2.1.Tree类
魔法方法:
构造函数:新建一棵树或通过深拷贝、浅拷贝方式复制一棵树

Tree(self, tree=None, deep=False)

len取长度:返回树的节点个数,同Tree.size()

len(Tree)

str字符串:Tree对象转换为str对象,可输出

str(Tree)

unicode字符串:Tree对象转换为unicode对象,可输出

unicode(Tree)

方法:

add_node(self, node, parent=None)

向树添加一个node节点,该节点为Node类对象,其父节点为parent

all_nodes(self)

以list返回所有节点

children(self, nid)

返回以nid为标识(identifier)子节点,nid不存在则返回list为空

contains(self, nid)

检查树中是否包含以nid为标识的节点

create_node(self, tag=None, identifier=None, parent=None, data=None)

以parent为父节点,在树上创建一个节点(类似于创建Node对象,在add_node添加Node)

depth(self, node=None)

返回树的深度(int),若给定node则返回以该节点为根的树的深度

expand_tree(self, nid=None, mode=1, filter=None, key=None, reverse=False)

Python生成器,松散地基于 John R. Anderson, Albert T. Corbett, and Brian J. Reiser的一个算法 (’Essential LISP’ , page 239-241)

UPDATE: the @filter function is performed on Node object during traversing.
UPDATE: the @key and @reverse are present to sort nodes at each level.

get_node(self, nid)

返回以nid为标识的节点,nid不存在则返回为空

is_branch(self, nid)

返回以nid为节点的子节点标识(identifier)的list列表,nid不存在则返回list为空

leaves(self, root=None)

返回所有叶节点对象list列表,若给定root则返回以root为根节点的树的所有叶节点对象list列表

level(self, nid, filter=None)

返回指定深度的所有节点,根节点按深度0计算
Update: @filter params is added to calculate level passing exclusive nodes.

link_past_node(self, nid)

将某节点的父节点与子节点链接的方法,将该节点从树上删除

比如, 一个a -> b -> c树 ,删除b节点, 则剩下a -> c树

move_node(self, source, destination)

将source的节点移动至destination的子节点

parent(self, nid)

返回以nid为标识的节点的父节点

paste(self, nid, new_tree, deepcopy=False)

粘贴树,通过连接new_tree的根节点与nid标识的节点,设置deepcopy可进行深拷贝
Update: add @deepcopy of pasted tree.

paths_to_leaves(self)

取得根节点到每一个叶节点的标识路径,返回值为标识list列表的list列表(二重列表),根节点不省略

比如一棵树:

Harry
|___ Bill
|___ Jane
| |___ Diane
| |___ George
| |___ Jill
| |___ Mary
| |___ Mark
1

输出结果:

[['harry', 'jane', 'diane', 'mary'],
['harry', 'jane', 'mark'],
['harry', 'jane', 'diane', 'george', 'jill'],
['harry', 'bill']]
remove_node(self, identifier)

移除以nid标识的节点,同时移除其所有的子节点
返回值为移除的节点个数

remove_subtree(self, nid)

移除以nid标识为根节点的一棵子树
返回值为移除该子树的树,nid不存在则返回一个空树

该方法类似于remove_node(self,nid) 实现效果相同但返回值不同:

remove_node 返回移除的节点个数
remove_subtree 返回移除该子树的树

建议使用remove_node来删除节点,因为remove_subtree将消耗内存以存储新树(返回值)

rsearch(self, nid, filter=None)

遍历从以nid为标识的节点到根节点的路径(枝)

save2file(self, filename, nid=None, level=0, idhidden=True, filter=None, key=None, reverse=False, line_type=u'ascii-ex', data_property=None)

将树保存到文件,以作离线分析

show(self, nid=None, level=0, idhidden=True, filter=None, key=None, reverse=False, line_type=u'ascii-ex', data_property=None)

输出树结构

siblings(self, nid)

返回以nid为标识的节点的兄弟节点
返回值为兄弟节点list列表,根节点无兄弟节点,返回空列表

size(self, level=None)

返回指定深度(level)节点个数,若无指定则返回整棵树节点个数

subtree(self, nid)

浅拷贝方式建立一个以nid为标识的节点作为根节点的子树,nid不存在则返回一个空树

若使用深拷贝,则请使用构造函数建立新树,如下:

e.g.

new_tree = Tree(t.subtree(t.root), deep=True)
to_dict(self, nid=None, key=None, sort=True, reverse=False, with_data=False)

将树转换为dict字典

to_json(self, with_data=False, sort=True, reverse=False)

将树转换为JSON格式输出

2.2.Node类
魔法方法:
构造函数:新建一个Node节点对象

变量 名称 说明
tag 标签 树输出时显示,默认为随机值
identifier 标识 树中唯一,不可重复,默认为随机值
data 数据 存储节点中数据

Node(self, tag=None, identifier=None, expanded=True, data=None)

方法:

is_leaf(self)

检查该节点是否是叶节点,返回布尔值

is_root(self)

检查该节点是否是根节点,返回布尔值

update_bpointer(self, nid)

设置_bpointer指针

update_fpointer(self, nid, mode=0)

设置_fpointer指针

3.实际应用

来源于官方帮助文档:treelib.readthedocs.io

3.1.基本用法
下面的实例,展示了建立一棵树的基本方法

 >>> from treelib import Node, Tree
>>> tree = Tree()
>>> tree.create_node("Harry", "harry") # root node
>>> 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")
>>> tree.show()
Harry
├── Bill
└── Jane
├── Diane
│ └── Mary
└── Mark

3.2.API 样例
下面根据上述的数作为例子,展示一部分API用法样例
* 例1:利用特殊方法扩展一棵树

 >>> print(','.join([tree[node].tag for node in \
tree.expand_tree(mode=Tree.DEPTH)]))
Harry,Bill,Jane,Diane,Mary,Mark

例2:利用自定义过滤扩展一棵树

 >>> print(','.join([tree[node].tag for node in \
tree.expand_tree(filter = lambda x: \
x.identifier != 'diane')]))
Harry,Bill,Jane,Mark

例3:获得以“‘diane”为根节点的子树

 >>> sub_t = tree.subtree('diane')
>>> sub_t.show()
Diane
└── Mary

例4:复制以“‘diane”为根节点的子树

 >>> new_tree = Tree()
>>> new_tree.create_node("n1", 1) # root node
>>> new_tree.create_node("n2", 2, parent=1)
>>> new_tree.create_node("n3", 3, parent=1)
>>> tree.paste('bill', new_tree)
>>> tree.show()
Harry
├── Bill
│ └── n1
│ ├── n2
│ └── n3
└── Jane
├── Diane
│ └── Mary
└── Mark

例5:从树上删除已存在节点

 >>> tree.remove_node(1)
>>> tree.show()
Harry
├── Bill
└── Jane
├── Diane
│ └── Mary
└── Mark

例6:将节点移动至另一父节点

 >>> tree.move_node('mary', 'harry')
>>> tree.show()
Harry
├── Bill
├── Jane
│ ├── Diane
│ └── Mark
└── Mary

例7:获得树深度

>>> tree.depth()
2

例8:获得节点所在深度

>>> node = tree.get_node("bill")
>>> tree.depth(node)
1

例9:输出树结构
以“ascii-em”形式输出:

>>> tree.show(line_type="ascii-em")
Harry
╠══ Bill
╠══ Jane
║ ╠══ Diane
║ ╚══ Mark
╚══ Mary

以JSON格式输出:

>>> print(tree.to_json(with_data=True))
{"Harry": {"data": null, "children": [{"Bill": {"data": null}}, {"Jane": {"data": null, "children": [{"Diane": {"data": null}}, {"Mark": {"data": null}}]}}, {"Mary": {"data": null}}]}}

3.3.更多用法
有时,你需要树来存储你的数据结构,在最新版本的treelib当中支持了.data属性,可以存储任何数据。
比如,定义一个Flower类:

>>> class Flower(object): \
    def __init__(self, color): \
    self.color = color

于是可以建立Flower树:

>>> ftree = Tree()
>>> ftree.create_node("Root", "root", data=Flower("black"))
>>> ftree.create_node("F1", "f1", parent='root', data=Flower("white"))
>>> ftree.create_node("F2", "f2", parent='root', data=Flower("red"))

按照.data的属性输出树结构:

 >>> ftree.show(data_property="color")
black
├── white
└── red

注意:在1.2.5版本之前,你需要继承并重写Node类方法,比如:

 >>> class FlowerNode(treelib.Node): \
    def __init__(self, color): \
      self.color = color
>>> # create a new node
>>> fnode = FlowerNode("white")

————————————————
版权声明:本文为CSDN博主「KAlbertLee」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/KAlbertLee/article/details/70158015

Python Treelib 多叉树 数据结构 中文使用帮助文档的更多相关文章

  1. (转载)中文Appium API 文档

    该文档是Testerhome官方翻译的源地址:https://github.com/appium/appium/tree/master/docs/cn官方网站上的:http://appium.io/s ...

  2. 中文Appium API 文档

    该文档是Testerhome官方翻译的源地址:https://github.com/appium/appium/tree/master/docs/cn官方网站上的:http://appium.io/s ...

  3. centos6编译安装zabbix3.0和中文支持整理文档

    编者按: 最近公司部分业务迁移机房,为了更方便的监控管理主机资源,决定上线zabbix监控平台.运维人员使用2.4版本的进行部署,个人在业余时间尝鲜,使用zabbix3.0进行部署,整理文档如下,仅供 ...

  4. eclipse 中使用中文JAVA api文档

    http://hi.baidu.com/danghj/item/7625a1be20946e43ba0e1202在eclipse中使用中文JAVA api文档Sun 官方的中文版 Java API 文 ...

  5. flexpaper上传带中文名字的文档,在页面显示若出现404错误时,请在server.xml文件中进行编码utf-8

    flexpaper上传带中文名字的文档,在页面显示若出现404错误时,请在server.xml文件中进行编码utf-8

  6. 学习笔记CB002:词干提取、词性标注、中文切词、文档分类

    英文词干提取器,import nltk,porter = nltk.PorterStemmer(),porter.stem('lying') . 词性标注器,pos_tag处理词序列,根据句子动态判断 ...

  7. Python小爬虫-自动下载三亿文库文档

    新手学python,写了一个抓取网页后自动下载文档的脚本,和大家分享. 首先我们打开三亿文库下载栏目的网址,比如专业资料(IT/计算机/互联网)http://3y.uu456.com/bl-197?o ...

  8. python优秀库 - 使用xmltodict解析xml文档

    上次讲到如何使用BeautifulSoup解析XML文档,今天发现另外一个python库xmltodict(https://github.com/martinblech/xmltodict)也很简单. ...

  9. Python sphinx-build在Windows系统中生成Html文档

    看到前同事发布的“Markdown/reST 文档发布流水线”基于TFS.Docker.Azure等工具和平台进行文档发布的介绍说明,不得不在心中暗暗竖起大拇指.这套模式,实现了文档编写后版本管理.发 ...

随机推荐

  1. c# 第33节 类的封装--访问修饰符

    本节内容: 1:封装的简介 2:封装怎么实现 3:访问修饰符 1:封装的简介 2:封装怎么实现 3:访问修饰符 4:访问修饰符注意点

  2. 201271050130-滕江南-《面向对象程序设计(java)》第十六周学习总结

    201271050130-滕江南-<面向对象程序设计(java)>第十六周学习总结 博文正文开头格式:(2分) 项目 内容 这个作业属于哪个课程 https://www.cnblogs.c ...

  3. monkey参数

    一.参数分类 常规类参数:包括帮助参数和日志信息参数. 帮助类参数:monkey -h     -- 输出monkey命令使用指导 日志信息参数:monkey -v <event-count&g ...

  4. 洛谷 P5596 【XR-4】题

    洛谷 P5596 [XR-4]题 洛谷传送门 题目描述 小 X 遇到了一道题: 给定自然数 a,ba,b,求满足下列条件的自然数对 (x,y)(x,y) 的个数: y^2 - x^2 = ax + b ...

  5. 1130不允许连接到MySql server

    连接远程服务器mysql时,报错: 1130-host ... is not allowed to connect to this MySql server 这是因为默认只让localhost的主机连 ...

  6. Unity Profiler 记录

    版本 Unity 2018.4.6f1 空包 development build 魅蓝 note3 OPPO R9 VIVO x9 华为 P8 青春版 小米 8 SE iphone se Other ...

  7. matplotlib动态绘图

    目录 package Process 解决中文乱码问题 simple_plot() scatter_plot() three_dimension_scatter() Jupyter notebook ...

  8. BFS(四):搜索状态判重

    在采用广度优先算法进行搜索时,一个需要重点注意的是在搜索过程中判重和去重.前面介绍的几个例子中,判重都较简单,如采用vis[]数组,若vis[i]==0,则i未访问过,i入队列:若vis[i]!=0, ...

  9. ndt算法学习

    NDT算法原理: NDT算法的基本思想是先根据参考数据(reference scan)来构建多维变量的正态分布, 如果变换参数能使得两幅激光数据匹配的很好,那么变换点在参考系中的概率密度将会很大. 因 ...

  10. LeetCode 739:每日温度 Daily Temperatures

    题目: 根据每日 气温 列表,请重新生成一个列表,对应位置的输入是你需要再等待多久温度才会升高超过该日的天数.如果之后都不会升高,请在该位置用 0 来代替. 例如,给定一个列表 temperature ...