树,对于计算机编程语言来说是一个重要的数据结构。它具有广泛的应用,比如文件系统的分层数据结构和机器学习中的一些算法。这里创建了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)

方法:

  1. add_node(self, node, parent=None)

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

  1. all_nodes(self)

以list返回所有节点

  1. children(self, nid)

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

  1. contains(self, nid)

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

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

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

  1. depth(self, node=None)

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

  1. 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.

  1. get_node(self, nid)

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

  1. is_branch(self, nid)

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

  1. leaves(self, root=None)

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

  1. level(self, nid, filter=None)

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

  1. link_past_node(self, nid)

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

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

  1. move_node(self, source, destination)

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

  1. parent(self, nid)

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

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

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

  1. paths_to_leaves(self)

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

比如一棵树:

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

输出结果:

  1. [['harry', 'jane', 'diane', 'mary'],
  2. ['harry', 'jane', 'mark'],
  3. ['harry', 'jane', 'diane', 'george', 'jill'],
  4. ['harry', 'bill']]
  1. remove_node(self, identifier)

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

  1. remove_subtree(self, nid)

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

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

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

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

  1. rsearch(self, nid, filter=None)

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

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

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

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

输出树结构

  1. siblings(self, nid)

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

  1. size(self, level=None)

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

  1. subtree(self, nid)

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

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

e.g.

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

将树转换为dict字典

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

将树转换为JSON格式输出

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

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

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

方法:

  1. is_leaf(self)

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

  1. is_root(self)

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

  1. update_bpointer(self, nid)

设置_bpointer指针

  1. update_fpointer(self, nid, mode=0)

设置_fpointer指针

3.实际应用

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

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

  1. >>> from treelib import Node, Tree
  2. >>> tree = Tree()
  3. >>> tree.create_node("Harry", "harry") # root node
  4. >>> tree.create_node("Jane", "jane", parent="harry")
  5. >>> tree.create_node("Bill", "bill", parent="harry")
  6. >>> tree.create_node("Diane", "diane", parent="jane")
  7. >>> tree.create_node("Mary", "mary", parent="diane")
  8. >>> tree.create_node("Mark", "mark", parent="jane")
  9. >>> tree.show()
  10. Harry
  11. ├── Bill
  12. └── Jane
  13. ├── Diane
  14. └── Mary
  15. └── Mark

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

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

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

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

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

  1. >>> sub_t = tree.subtree('diane')
  2. >>> sub_t.show()
  3. Diane
  4. └── Mary

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

  1. >>> new_tree = Tree()
  2. >>> new_tree.create_node("n1", 1) # root node
  3. >>> new_tree.create_node("n2", 2, parent=1)
  4. >>> new_tree.create_node("n3", 3, parent=1)
  5. >>> tree.paste('bill', new_tree)
  6. >>> tree.show()
  7. Harry
  8. ├── Bill
  9. └── n1
  10. ├── n2
  11. └── n3
  12. └── Jane
  13. ├── Diane
  14. └── Mary
  15. └── Mark

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

  1. >>> tree.remove_node(1)
  2. >>> tree.show()
  3. Harry
  4. ├── Bill
  5. └── Jane
  6. ├── Diane
  7. └── Mary
  8. └── Mark

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

  1. >>> tree.move_node('mary', 'harry')
  2. >>> tree.show()
  3. Harry
  4. ├── Bill
  5. ├── Jane
  6. ├── Diane
  7. └── Mark
  8. └── Mary

例7:获得树深度

  1. >>> tree.depth()
  2. 2

例8:获得节点所在深度

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

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

  1. >>> tree.show(line_type="ascii-em")
  2. Harry
  3. ╠══ Bill
  4. ╠══ Jane
  5. ╠══ Diane
  6. ╚══ Mark
  7. ╚══ Mary

以JSON格式输出:

  1. >>> print(tree.to_json(with_data=True))
  2. {"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类:

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

于是可以建立Flower树:

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

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

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

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

  1. >>> class FlowerNode(treelib.Node): \
  2.     def __init__(self, color): \
  3.       self.color = color
  4. >>> # create a new node
  5. >>> 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. Pwnable-fd

    打开Ubuntu输入ssh fd@pwnable.kr -p2222,连接之后输入密码guest 之后就是ls -l看看里面的文件和权限,fd.fd.c.flag 看看fd.c的源码 #include ...

  2. JAVA字符串截取与求模

    public class splitdemo { /** * @param args */ public static void main(String[] args) { // TODO Auto- ...

  3. Linux上发布E卡通项目

    Linux上发布E卡通项目 使用的命令 ps -ef | grep java kill -9 22314 nohup java -jar smartcard-ms-0.0.1-SNAPSHOT.jar ...

  4. Win10 企业版ltsc 无法访问samba网络共享问题及解决!(转)

    1.本地安全策略,本地策略-安全选项,需要修改成默认的值的修改方式:查找注册表浏览到 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\LSA直接 ...

  5. Flutter基础系列之混合开发(二)

    1.混合开发的场景 1.1作为独立页面加入 这是以页面级作为独立的模块加入,而不是页面的某个元素. 原生页面可以打开Flutter页面 Flutter页面可以打开原生页面 1.2作为页面的一部分嵌入 ...

  6. windows上安装python2和python3虚拟环境

    一.windows上安装 1.安装python 分别安装了Python2和Python3 python3.7默认安装目录 C:\Users\Administrator\AppData\Local\Pr ...

  7. vue 移动端上传图片结合localResizeIMG插件进行图片压缩

    localResizeIMG插件的功能是将图片进行压缩,然后转换成base64传给后台. 首先, npm i lrz -save 然后,再main.js里面引入lrz import lrz from ...

  8. jQuery 源码分析(五) map函数 $.map和$.fn.map函数 详解

    $.map() 函数用于使用指定函数处理数组中的每个元素(或对象的每个属性),并将处理结果封装为新的数组返回,该函数有三个参数,如下: elems Array/Object类型 指定的需要处理的数组或 ...

  9. vs2017离线包下载安装并且不占用C盘空间使用教程

    安装vs2017,前提是你的环境是.NET4.6,VS2017在下载好安装程序安装的时候,会根据你选择的功能模块来下载所需要的安装程序,微软.安卓和苹果等平台的SDK.模拟器和第三方扩展功能等会在用户 ...

  10. 状态(State)模式--设计模式

    定义与特点 1.1 定义 状态模式允许一个对象在其内部状态改变的时候改变其行为.这个对象看上去就像是改变了它的类一样. 1.2 特点 状态模式优点: 封装了转换规则,并枚举可能的状态,它将所有与某个状 ...