API
Node classes
- class littletree.BaseNode(identifier='node', children=(), parent=None)[source]
Bases:
Generic
[TIdentifier
],MutableTree
,TreeMixin
A basic tree node that can have a single parent and multiple children.
The
BaseNode
forms the foundation for building hierarchical tree structures. Each node can be uniquely identified by its name within its parent’s scope and can be navigated viaNodePath
objects.Compared to
Node
this class is more basic and useful for subclassing.- Parameters:
identifier (TIdentifier)
children (Mapping[TIdentifier, TNode] | Iterable[TNode])
parent (TNode | None)
- add_child(node, check_loop=True)[source]
Add a single child node.
The child’s parent will be set to this node. A
DuplicateChildError
is raised if another child with the same name already exists. ADuplicateParentError
will be raised if this child already has a parent.- Parameters:
node (TNode) – Child to add.
check_loop (bool) – Whether to check if adding child results in a loop.
- Returns:
- property children: ValuesView[TNode]
Children of this node.
- copy(_memo=None, keep=None)[source]
Make a shallow copy or deepcopy if memo is passed.
- Return type:
TNode
- detach()[source]
Remove node from its parent.
This is especially useful when moving the node to a different tree or branch. :return: self
- Return type:
TNode
- dict_class
alias of
dict
- property identifier: Any
Key to identify this node. This can not be equal to an identifier of a sibling.
- property is_leaf: bool
Whether this node is a leaf (does not have children).
- iter_together(other)[source]
Yield all nodes in self with similar nodes in other.
If no equivalent node can be found in other, yield node from self with None
- Return type:
Tuple[TNode, TNode | None]
- property parent: TNode | None
Parent of this node or None.
- pop(identifier)[source]
Remove and return node with identifier or None.
- Parameters:
identifier (TIdentifier)
- Return type:
TNode | None
- property root: TNode
Root of tree.
- sort_children(key=None, recursive=False, reverse=False)[source]
Sort children
- Parameters:
key (Callable[[TNode], Any] | None) – Function to sort by. If not given, sort on identifier.
recursive (bool) – Whether all descendants should be sorted or just children.
reverse (bool) – Whether to sort in reverse order
- Return type:
None
- update(other, mode='copy', check_loop=True)[source]
Add multiple nodes at once.
This is faster than repeatedly calling setitem when adding many children at once.
About time complexity: Let n be the number of nodes added, d be the depth of the tree, C be copy time:
T(n) = O(nC + d) if
check_loop
and notconsume
;T(n) = O(n + d) if
check_loop
and (consume
or no child has a parent);T(n) = O(nC) if not
check_loop
and notconsume
;T(n) = O(n) if not
check_loop
and (consume
or no child has a parent).
- Parameters:
other (Mapping[TIdentifier, TNode] | Iterable[TNode] | TNode) –
Source of other nodes. Other could be:
mapping Keys will become new identifiers
iterable Nodes will be added
node Same as self.update(other.children) but implemented more efficiently.
mode (str) –
How to handle nodes that already have a parent:
”copy”: These nodes will be copied and remain in old tree
”detach”: These nodes will be detached from old tree
check_loop (bool) – If True, raises LoopError if a cycle is created.
- Returns:
None
- Return type:
None
- class littletree.Node(data=MISSING, identifier=MISSING, children=(), parent=None)[source]
Bases:
BaseNode
[TIdentifier
],Generic
[TIdentifier
,TData
]- Parameters:
data (TData)
identifier (TIdentifier)
children (Mapping[TIdentifier, TNode] | Iterable[TNode])
parent (TNode | None)
- compare(other, keep_equal=False)[source]
Compare two trees to one another.
If keep_equal is False (default), all nodes where data is equal will be removed.
>>> tree = Node('apples', identifier='fruit') >>> other_tree = Node('oranges') >>> tree.compare(other_tree) Node({'self': 'apples', 'other': 'oranges'}, identifier='fruit)
- Parameters:
other (TNode)
- Return type:
TNode | None
- copy(memo=None, *, keep=None, deep=False)[source]
Make a shallow copy or deepcopy if memo is passed.
- Return type:
TNode
- equals(other)[source]
Recursively check if two (sub)trees are the same.
Each node in the subtree must have the same identifier and same data.
- Parameters:
self (TNode)
other (TNode)
- Return type:
bool
- classmethod from_dict(data, data_field='data', **kwargs)[source]
Import from nested dictionary.
- Return type:
TNode
- classmethod from_newick(newick, root=None, data_field='data', **kwargs)[source]
Import from newick.
- Return type:
TNode
- classmethod from_relations(relations, root=None, data_field='data', **kwargs)[source]
Import from parent-child list.
- Return type:
TNode
- classmethod from_rows(rows, root=None, data_field='data', **kwargs)[source]
Import from list of path-rows.
- Return type:
TNode
- similar_to(other)[source]
Check if two trees are similar.
Trees are similar if they have the same structure and the same data.
Change from version 0.5.0: - Two trees can now be equal if the roots have a different identifier.
- Parameters:
self (TNode)
other (TNode)
- Return type:
bool
- class littletree.TreeMixin[source]
Bases:
Tree
- to_image(*args, **kwargs)[source]
Convert tree to image.
This return bytes. Use
to_pillow
for an Image abstraction.
Serializers
- class littletree.serializers.DictSerializer(factory=None, identifier_name='identifier', children_name='children', fields=(), data_field=None)[source]
Bases:
object
Serializer to/from a nested dictionary.
- Parameters:
factory (Type[TNode])
identifier_name (TIdentifier)
children_name (str | None)
fields (Sequence[str])
data_field (str)
- class littletree.serializers.NetworkXSerializer(factory=None, fields=(), data_field=None)[source]
Bases:
object
Serializer to/from a networkx graph.
- Parameters:
factory (Callable[[], TNode])
fields (Sequence[str])
data_field (str)
- class littletree.serializers.NewickSerializer(factory=None, fields=(), data_field=None, dialect=None, **kwargs)[source]
Bases:
object
Serialize to/from the newick tree format. A formal description is here: http://biowiki.org/wiki/index.php/Newick_Format
A few dialects are supported (default: safe-nhx):
newick
is the most basic dialect without extra featuresnhx
enables an extension called New Hampshire X formatThis extension is described here: https://www.cs.mcgill.ca/~birch/doc/forester/NHX.pdf
safe-nhx
is similar to nhx, but xml-escaping is applied on reserved newick characters
- Parameters:
factory (Callable[[], TNode])
fields (Sequence[str])
data_field (str)
dialect (str | Dialect | Mapping)
- class littletree.serializers.RelationSerializer(factory=None, child_name='identifier', parent_name='parent', fields=(), data_field=None)[source]
Bases:
object
Serializes a tree to a list of parent-children relations.
- Parameters:
factory (Callable[[], TNode])
child_name (str)
parent_name (str)
fields (Sequence[str])
data_field (str)
- class littletree.serializers.RowSerializer(factory=None, path_name='path', sep='/', fields=(), data_field=None)[source]
Bases:
object
Serializes a tree to a list of dicts containing path and data.
- Parameters:
factory (Callable[[], TNode])
path_name (str | Sequence[str] | None)
sep (str | None)
fields (Sequence[str])
data_field (str)
Exceptions
- exception littletree.exceptions.DuplicateParentError(node)[source]
Bases:
TreeException
Operation would add multiple parents to a node.
- exception littletree.exceptions.DuplicateChildError(node, identifier)[source]
Bases:
TreeException
Operation would add multiple children with the same identifier to the same parent.
- exception littletree.exceptions.LoopError(node, ancestor)[source]
Bases:
TreeException
Operation would create a loop.