Simple, lightweight and extensible Tree data structure.
Feel free to share info about your anytree project.
- Installation
- Introduction
- Overview
- Basics
- Detach/Attach Protocol
- Custom Separator
- API
- Node Classes
- Tree Iteration
- Tree Rendering
- Searching
- Cached Searching
- Node Resolution
- Tree Walking
- Utilities
- Importer
- Dictionary Importer
- JSON Importer
- Exporter
- Dictionary Exporter
- JSON Exporter
- Dot Exporter
- Tricks
- Read-only Tree
- YAML Import/Export
- Multidimensional Trees
- Weighted Edges
Getting started¶
Usage is simple.
Construction
>>> from anytree import Node, RenderTree >>> udo = Node["Udo"] >>> marc = Node["Marc", parent=udo] >>> lian = Node["Lian", parent=marc] >>> dan = Node["Dan", parent=udo] >>> jet = Node["Jet", parent=dan] >>> jan = Node["Jan", parent=dan] >>> joe = Node["Joe", parent=dan]
Node
>>> print[udo] Node['/Udo'] >>> print[joe] Node['/Udo/Dan/Joe']
Tree
>>> for pre, fill, node in RenderTree[udo]: ... print["%s%s" % [pre, node.name]] Udo ├── Marc │ └── Lian └── Dan ├── Jet ├── Jan └── Joe
For details see Node
and
RenderTree
.
Visualization
>>> from anytree.exporter import DotExporter >>> # graphviz needs to be installed for the next line! >>> DotExporter[udo].to_picture["udo.png"]
The
DotExporter
can be started at any node and has various formatting hookups:
>>> DotExporter[dan, ... nodeattrfunc=lambda node: "fixedsize=true, width=1, height=1, shape=diamond", ... edgeattrfunc=lambda parent, child: "style=bold" ... ].to_picture["dan.png"]
Manipulation
A second tree:
>>> mary = Node["Mary"] >>> urs = Node["Urs", parent=mary] >>> chris = Node["Chris", parent=mary] >>> marta = Node["Marta", parent=mary] >>> print[RenderTree[mary]] Node['/Mary'] ├── Node['/Mary/Urs'] ├── Node['/Mary/Chris'] └── Node['/Mary/Marta']
Append:
>>> udo.parent = mary >>> print[RenderTree[mary]] Node['/Mary'] ├── Node['/Mary/Urs'] ├── Node['/Mary/Chris'] ├── Node['/Mary/Marta'] └── Node['/Mary/Udo'] ├── Node['/Mary/Udo/Marc'] │ └── Node['/Mary/Udo/Marc/Lian'] └── Node['/Mary/Udo/Dan'] ├── Node['/Mary/Udo/Dan/Jet'] ├── Node['/Mary/Udo/Dan/Jan'] └── Node['/Mary/Udo/Dan/Joe']
Subtree rendering:
>>> print[RenderTree[marc]] Node['/Mary/Udo/Marc'] └── Node['/Mary/Udo/Marc/Lian']
Cut:
>>> dan.parent = None >>> print[RenderTree[dan]] Node['/Dan'] ├── Node['/Dan/Jet'] ├── Node['/Dan/Jan'] └── Node['/Dan/Joe']
Extending any python class to become a tree node
The enitre tree magic is encapsulated by NodeMixin
, add it as base class and the class becomes a tree node:
>>> from anytree import NodeMixin, RenderTree >>> class MyBaseClass[object]: # Just an example of a base class ... foo = 4 >>> class MyClass[MyBaseClass, NodeMixin]: # Add Node feature ... def __init__[self, name, length, width, parent=None, children=None]: ... super[MyClass, self].__init__[] ... self.name = name ... self.length = length ... self.width = width ... self.parent = parent ... if children: # set children only if given ... self.children = children
Just set the parent attribute to reflect the tree relation:
>>> my0 = MyClass['my0', 0, 0] >>> my1 = MyClass['my1', 1, 0, parent=my0] >>> my2 = MyClass['my2', 0, 2, parent=my0]
>>> for pre, fill, node in RenderTree[my0]: ... treestr = u"%s%s" % [pre, node.name] ... print[treestr.ljust[8], node.length, node.width] my0 0 0 ├── my1 1 0 └── my2 0 2
The children can be used likewise:
>>> my0 = MyClass['my0', 0, 0, children=[ ... MyClass['my1', 1, 0], ... MyClass['my2', 0, 2], ... ]]
>>> for pre, fill, node in RenderTree[my0]: ... treestr = u"%s%s" % [pre, node.name] ... print[treestr.ljust[8], node.length, node.width] my0 0 0 ├── my1 1 0 └── my2 0 2