0
# Tree Construction and Node Management
1
2
Comprehensive functionality for creating trees, adding nodes, and managing hierarchical structures. This module provides the foundation for building tree-based data structures with automatic relationship management and validation.
3
4
## Capabilities
5
6
### Tree Creation
7
8
Create new tree instances with optional copying, custom node classes, and unique identifiers.
9
10
```python { .api }
11
def __init__(tree=None, deep=False, node_class=None, identifier=None):
12
"""
13
Initialize a new tree or copy an existing tree.
14
15
Parameters:
16
- tree: Tree object to copy from (optional)
17
- deep: bool, perform deep copy if True
18
- node_class: Custom Node class to use
19
- identifier: Unique identifier for this tree instance
20
"""
21
```
22
23
**Usage Examples:**
24
25
```python
26
from treelib import Tree
27
28
# Create empty tree
29
tree = Tree()
30
31
# Create tree with custom identifier
32
tree = Tree(identifier="my_tree")
33
34
# Shallow copy of existing tree
35
tree_copy = Tree(existing_tree)
36
37
# Deep copy with independent data
38
tree_deep = Tree(existing_tree, deep=True)
39
```
40
41
### Node Creation
42
43
Create and add nodes to the tree structure with flexible parameter options.
44
45
```python { .api }
46
def create_node(tag=None, identifier=None, parent=None, data=None) -> Node:
47
"""
48
Create and add a new node to the tree.
49
50
Parameters:
51
- tag: str, human-readable label for the node
52
- identifier: str, unique ID (auto-generated if None)
53
- parent: str, parent node identifier
54
- data: Any, custom data payload
55
56
Returns:
57
Node object that was created and added
58
"""
59
```
60
61
**Usage Examples:**
62
63
```python
64
# Create root node
65
tree.create_node("Root", "root")
66
67
# Create child with auto-generated ID
68
node = tree.create_node("Child", parent="root")
69
70
# Create node with custom data
71
tree.create_node("User", "user1", parent="root",
72
data={"name": "Alice", "role": "admin"})
73
74
# Create with all parameters
75
tree.create_node(tag="Project", identifier="proj1",
76
parent="root", data={"budget": 50000})
77
```
78
79
### Node Addition
80
81
Add existing Node objects to the tree structure.
82
83
```python { .api }
84
def add_node(node, parent=None) -> None:
85
"""
86
Add an existing Node object to the tree.
87
88
Parameters:
89
- node: Node object to add
90
- parent: str, parent node identifier (optional for root)
91
"""
92
```
93
94
**Usage Examples:**
95
96
```python
97
from treelib import Node, Tree
98
99
# Create standalone node
100
node = Node("Standalone", "node1", data={"type": "external"})
101
102
# Add to tree
103
tree.add_node(node, parent="root")
104
105
# Add as root (if tree is empty)
106
root_node = Node("Root", "root")
107
tree.add_node(root_node)
108
```
109
110
### Node Access and Queries
111
112
Safely access and query nodes within the tree structure.
113
114
```python { .api }
115
def get_node(nid) -> Node | None:
116
"""
117
Safely retrieve a node without raising exceptions.
118
119
Parameters:
120
- nid: str, node identifier
121
122
Returns:
123
Node object if found, None otherwise
124
"""
125
126
def __getitem__(key) -> Node:
127
"""
128
Get node by identifier using bracket notation.
129
130
Parameters:
131
- key: str, node identifier
132
133
Returns:
134
Node object
135
136
Raises:
137
NodeIDAbsentError if node doesn't exist
138
"""
139
140
def __contains__(identifier) -> bool:
141
"""
142
Check if node exists using 'in' operator.
143
144
Parameters:
145
- identifier: str, node identifier
146
147
Returns:
148
bool, True if node exists
149
"""
150
151
def contains(nid) -> bool:
152
"""
153
Check if node exists in tree.
154
155
Parameters:
156
- nid: str, node identifier
157
158
Returns:
159
bool, True if node exists
160
"""
161
```
162
163
**Usage Examples:**
164
165
```python
166
# Safe node access
167
node = tree.get_node("user1")
168
if node:
169
print(f"Found: {node.tag}")
170
171
# Direct access (may raise exception)
172
user_node = tree["user1"]
173
174
# Membership testing
175
if "user1" in tree:
176
print("User exists")
177
178
# Alternative membership test
179
exists = tree.contains("user1")
180
```
181
182
### Node Collection Access
183
184
Retrieve and iterate over collections of nodes.
185
186
```python { .api }
187
def all_nodes() -> list[Node]:
188
"""
189
Get all nodes as a list.
190
191
Returns:
192
list[Node], all nodes in the tree
193
"""
194
195
def all_nodes_itr() -> Iterator[Node]:
196
"""
197
Get all nodes as an iterator for memory efficiency.
198
199
Returns:
200
Iterator[Node], iterator over all nodes
201
"""
202
203
def filter_nodes(func) -> Iterator[Node]:
204
"""
205
Filter nodes by custom function.
206
207
Parameters:
208
- func: callable, filtering function that takes Node and returns bool
209
210
Returns:
211
Iterator[Node], filtered nodes
212
"""
213
```
214
215
**Usage Examples:**
216
217
```python
218
# Get all nodes
219
all_nodes = tree.all_nodes()
220
print(f"Total nodes: {len(all_nodes)}")
221
222
# Memory-efficient iteration
223
for node in tree.all_nodes_itr():
224
if node.data and "admin" in node.data.get("role", ""):
225
print(f"Admin user: {node.tag}")
226
227
# Custom filtering
228
admin_nodes = tree.filter_nodes(
229
lambda n: n.data and n.data.get("role") == "admin"
230
)
231
```
232
233
### Tree Factory Methods
234
235
Create trees from various data sources.
236
237
```python { .api }
238
@classmethod
239
def from_map(cls, child_parent_dict, id_func=None, data_func=None) -> Tree:
240
"""
241
Create tree from child-parent mapping dictionary.
242
243
Parameters:
244
- child_parent_dict: dict, mapping of child -> parent relationships
245
- id_func: callable, function to generate node identifiers
246
- data_func: callable, function to generate node data
247
248
Returns:
249
Tree object constructed from the mapping
250
"""
251
```
252
253
**Usage Examples:**
254
255
```python
256
# Create from relationship mapping
257
relationships = {
258
"alice": "engineering",
259
"bob": "engineering",
260
"carol": "sales",
261
"engineering": "company",
262
"sales": "company",
263
"company": None # Root node
264
}
265
266
tree = Tree.from_map(relationships)
267
268
# With custom ID and data functions
269
tree = Tree.from_map(
270
relationships,
271
id_func=lambda x: x.lower().replace(" ", "_"),
272
data_func=lambda x: {"name": x, "created": datetime.now()}
273
)
274
```
275
276
### Tree Properties
277
278
Access fundamental tree properties and metadata.
279
280
```python { .api }
281
@property
282
def root() -> str | None:
283
"""
284
Get the identifier of the root node.
285
286
Returns:
287
str, root node identifier, or None if tree is empty
288
"""
289
290
@property
291
def identifier() -> str | None:
292
"""
293
Get the unique identifier of this tree instance.
294
295
Returns:
296
str, tree identifier, or None if not set
297
"""
298
299
@property
300
def nodes() -> dict[str, Node]:
301
"""
302
Get the internal nodes dictionary.
303
304
Returns:
305
dict[str, Node], mapping of node IDs to Node objects
306
"""
307
308
def __len__() -> int:
309
"""
310
Get the total number of nodes in the tree.
311
312
Returns:
313
int, number of nodes
314
"""
315
```
316
317
**Usage Examples:**
318
319
```python
320
# Access tree properties
321
print(f"Root node: {tree.root}")
322
print(f"Tree ID: {tree.identifier}")
323
print(f"Total nodes: {len(tree)}")
324
325
# Direct access to nodes dictionary (use with caution)
326
node_dict = tree.nodes
327
print(f"Node IDs: {list(node_dict.keys())}")
328
```
329
330
## Exception Handling
331
332
Common exceptions raised during tree construction and node management:
333
334
```python { .api }
335
class DuplicatedNodeIdError(Exception):
336
"""Raised when trying to add a node with existing identifier"""
337
338
class MultipleRootError(Exception):
339
"""Raised when tree would have multiple root nodes"""
340
341
class NodeIDAbsentError(Exception):
342
"""Raised when referencing non-existent node identifier"""
343
```
344
345
**Usage Examples:**
346
347
```python
348
from treelib import Tree, DuplicatedNodeIdError, NodeIDAbsentError
349
350
try:
351
tree.create_node("Duplicate", "existing_id")
352
except DuplicatedNodeIdError:
353
print("Node ID already exists")
354
355
try:
356
node = tree["missing_node"]
357
except NodeIDAbsentError:
358
print("Node not found")
359
```