Trees are a common data structure and there are many different ways to implement them. This package provides a common interface to access and operate on these objects.
Installing
Use pip to install abstracttree:
$ pip install --upgrade abstracttree
Usage
You can start by implementing the mixins below. Otherwise, a lot of trees are supported out of the box.
Mixins
graph TD;
Tree[Tree];
MutableTree[MutableTree];
DownTree[DownTree];
Tree[Tree];
MutableTree[MutableTree];
MutableDownTree[MutableDownTree];
MutableTree[MutableTree];
BinaryDownTree[BinaryDownTree];
BinaryTree[BinaryTree];
Tree-->MutableTree;
DownTree-->Tree;
DownTree-->MutableDownTree;
MutableDownTree-->MutableTree;
DownTree-->BinaryDownTree;
BinaryDownTree-->BinaryTree;
Tree-->BinaryTree;
| ABC | Inherits from | Abstract Methods | Mixin Methods |
|---|---|---|---|
DownTree |
children |
nodes, nodes.preorder(), nodes.postorder(), nodes.levelorder(), descendants, leaves, levels, levels.zigzag(), is_leaf, transform(), nid |
|
Tree |
DownTree |
parent |
root, is_root, ancestors, path, siblings |
MutableDownTree |
DownTree |
add_child(), remove_child() |
add_children() |
MutableTree |
MutableDownTree, Tree |
detach() |
|
BinaryDownTree |
DownTree |
left_child, right_child |
children, nodes.inorder(), descendants.inorder() |
BinaryTree |
BinaryDownTree, Tree |
For example, to create a simple tree with children (but no parent):
from abstracttree import DownTree, print_tree
class MyTree(DownTree):
def __init__(self, value, children=()):
self.value = value
self._children = children
def __str__(self):
return "MyTree " + str(self.value)
@property
def children(self):
return self._children
tree = MyTree(1, children=[MyTree(2), MyTree(3)])
print_tree(tree)
# This generates the following output:
# MyTree 1
# ├─ MyTree 2
# └─ MyTree 3
Generics
Unfortunately, not all trees inherit from the mixins above. Yet, some objects still have treelike behaviour. Therefore, AbstractTree provides support for a slightly weaker protocol.
The following objects are TreeLike:
- All objects that support
obj.childrenandobj.parent. - Builtins classes
pathlib.Pathandzipfile.Path. - Third party tree classes from anytree, bigtree, itertree and littletree.
The following objects are DownTreeLike:
- All objects that support
obj.children. - Anything implementing
DownTree. - Recursive collections like lists, tuples, sets, dicts. This can be useful when dealing with json-data.
This can be tested using isinstance:
isinstance(Path(r"C:\\Windows\System"), TreeLike) # True
isinstance(range(100), DownTreeLike) # True
isinstance(range(100), TreeLike) # False
isinstance(5, DownTreeLike) # False
isinstance("some text", DownTreeLike) # False (even though it might be considered a collection by python).
Basic functions
On downtreelikes:
children(node) # Children of node
label(node) # String representation of node (similar to str, but output excludes parent and children)
nid(node) # Address of node (similar to id, but supports delegates).
eqv(node1, node2) # Check if 2 nodes have the same identity (similar to is, but supports delegates)
Additionally, on treelikes:
parent(node) # Parent of node or None if node is root of its own tree.
root(node) # Find root of this tree.
Examples:
>>> from abstracttree import *
>>> children([1, 2, 3])
[1, 2, 3]
>>> children({"name": "Philip", "children": ["Pete", "Mariam"]})
[MappingItem(key="name", value="Philip"), MappingItem(key="children", value=["Pete", "Miriam"])]
>>> parent(Path(r"C:\\Windows\System"))
Path(r"C:\\Windows")
>>> label(Path(r"C:\\Windows\System"))
"System"
>>> eqv(Path(r"C:\\Windows\System"), Path(r"C:\\Windows\System"))
True
>>> eqv([1, 2, 3], [1, 2, 3])
False
Iterators
On downtreelikes:
nodes(tree) # Iterate through all nodes in tree (in no particular order).
descendants(node) # Children and grand-(grand-*)-children of node.
leaves(root) # Leaves reachable from root
If you want to iterate though the nodes in a specific order, use:
preorder(node) # Nodes in preorder (root comes first).
postorder(node) # Nodes in postorder (root comes last).
levelorder(node) # Nodes near the root come before later nodes.
These will return tuples with (node, item). The item-object contains information about the depth of the node.
Additionally, on treelikes:
ancestors(node) # Ancestors of node.
path(node) # Path from root to this node including this node.
siblings(node) # Siblings of node
Adapters
To upgrade a TreeLike to a full Tree use as_tree.
path_tree = as_tree(pathlib.Path("my_documents")) # Optionally pass `children`, `parent`, `label`.
# Iterate over all its descendants
for node in path_tree.descendants:
path_obj = node.value # Get back a Path-object from TreeAdapter
There is also TreeAdapter to help with classes that are very different.
Exporting
Export to various formats
print_tree(tree)
# If matplotlib is installed
plot_tree(tree)
# These may require graphviz or Pillow to be installed.
to_dot(tree)
to_mermaid(tree)
to_latex(tree)
to_reportlab(tree)
to_image(Path('.'), "filetree.png", how="dot")
to_image(DownTree, "tree_hierarchy.svg", how="mermaid")
to_pillow(tree).show()
Metadata
Release files for abstracttree 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| abstracttree-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Release files / abstracttree-0.2.2-py3-none-any.whl
| Download URL | abstracttree-0.2.2-py3-none-any.whl |
|---|---|
| Size | 28.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3038968d8d992246b6e19da29c0f5c056d686a0e8f978dbaabc3da3e7e35ff50
|
|
BLAKE2b-256 checksum How to use checksums |
99cf0a580f722c8490ddfa161f992bc7c4a108c4fc4019cc358f0000b68a7a53
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.0
|