Skip to content

Repository files navigation

logo nutree

Latest Version Tests codecov License Documentation Status Downloads

Nutree is a Python library for tree data structures with an intuitive, yet powerful, API.

Nutree trees and nodes follow Python's container conventions where it makes sense for a tree structure, while deliberately diverging where a literal list/Sequence analogy would be misleading.

__len__ returns the total number of nodes in the tree (or direct children of a node), __iter__ performs a depth-first traversal over descendants, and __contains__ tests membership using the same matching rules as lookup.

__getitem__ is value-based rather than positional: an int is matched against id(node) and node.data_id. Other values are matched against node.data. A lookup that finds no match raises KeyError; one that finds more than one match raises AmbiguousMatchError, which points you to find_first() or find_all() for explicit control. Because there is no meaningful notion of position in a tree, slicing and __reversed__ are intentionally not implemented — use traversal methods (iterate(), order-specific walks) when you need directional or ordered access instead.

Nutree Facts

Handle multiple references of single objects ('clones')
Search by name pattern, id, or object reference
Compare two trees and calculate patches
Unobtrusive handling of arbitrary objects
Save as DOT file and graphwiz diagram
Nodes can be plain strings or objects
(De)Serialize to (compressed) JSON
Save as Mermaid flow diagram
Multiple traversal methods
Generate random trees
Convert to RDF graph
Fully type annotated
Typed child nodes
Memory efficient
Pretty print
Navigation
Filtering
Fast

Example

A simple tree, with text nodes

from nutree import Tree, Node

tree = Tree("Store")

n = tree.add("Records")

n.add("Let It Be")
n.add("Get Yer Ya-Ya's Out!")

n = tree.add("Books")
n.add("The Little Prince")

tree.print()
Tree<'Store'>
├─── 'Records'
│    ├─── 'Let It Be'
│    ╰─── "Get Yer Ya-Ya's Out!"
╰─── 'Books'
     ╰─── 'The Little Prince'

Tree nodes wrap the data and also expose methods for navigation, searching, iteration, ...

records_node = tree["Records"]
assert isinstance(records_node, Node)
assert records_node.name == "Records"

print(records_node.first_child())
Node<'Let It Be', data_id=510268653885439170>

Nodes may be strings or arbitrary objects:

alice = Person("Alice", age=23, guid="{123-456}")
tree.add(alice)

# Lookup nodes by object, data_id, name pattern, ...
assert isinstance(tree[alice].data, Person)

del tree[alice]

Read the Docs for more.

About

A Python library for tree data structures with an intuitive, yet powerful API.

Topics

Resources

Stars

55 stars

Watchers

2 watching

Forks

Releases

Sponsor this project

Used by

Contributors

Languages