Hi you may give itertree a try [I'm the author].
The package goes in the direction of anytree package but with a bit different focus. The performance on huge trees [>100000 items] is much better and it deals with iterators to have effective filter mechanism.
>>>from itertree import *
>>>root=iTree['root']
>>># add some children:
>>>root.append[iTree['Africa',data={'surface':30200000,'inhabitants':1257000000}]]
>>>root.append[iTree['Asia', data={'surface': 44600000, 'inhabitants': 4000000000}]]
>>>root.append[iTree['America', data={'surface': 42549000, 'inhabitants': 1009000000}]]
>>>root.append[iTree['Australia&Oceania', data={'surface': 8600000, 'inhabitants': 36000000}]]
>>>root.append[iTree['Europe', data={'surface': 10523000 , 'inhabitants': 746000000}]]
>>># you might use __iadd__ operator for adding too:
>>>root+=iTree['Antarktika', data={'surface': 14000000, 'inhabitants': 1100}]
>>># for building next level we select per index:
>>>root[0]+=iTree['Ghana',data={'surface':238537,'inhabitants':30950000}]
>>>root[0]+=iTree['Niger', data={'surface': 1267000, 'inhabitants': 23300000}]
>>>root[1]+=iTree['China', data={'surface': 9596961, 'inhabitants': 1411780000}]
>>>root[1]+=iTree['India', data={'surface': 3287263, 'inhabitants': 1380004000}]
>>>root[2]+=iTree['Canada', data={'type': 'country', 'surface': 9984670, 'inhabitants': 38008005}]
>>>root[2]+=iTree['Mexico', data={'surface': 1972550, 'inhabitants': 127600000 }]
>>># extend multiple items:
>>>root[3].extend[[iTree['Australia', data={'surface': 7688287, 'inhabitants': 25700000 }], iTree['New Zealand', data={'surface': 269652, 'inhabitants': 4900000 }]]]
>>>root[4]+=iTree['France', data={'surface': 632733, 'inhabitants': 67400000 }]]
>>># select parent per TagIdx - remember in itertree you might put items with same tag multiple times:
>>>root[TagIdx['Europe'0]]+=iTree['Finland', data={'surface': 338465, 'inhabitants': 5536146 }]
The created tree can be rendered:
>>>root.render[]
iTree['root']
└──iTree['Africa', data=iTData[{'surface': 30200000, 'inhabitants': 1257000000}]]
└──iTree['Ghana', data=iTData[{'surface': 238537, 'inhabitants': 30950000}]]
└──iTree['Niger', data=iTData[{'surface': 1267000, 'inhabitants': 23300000}]]
└──iTree['Asia', data=iTData[{'surface': 44600000, 'inhabitants': 4000000000}]]
└──iTree['China', data=iTData[{'surface': 9596961, 'inhabitants': 1411780000}]]
└──iTree['India', data=iTData[{'surface': 3287263, 'inhabitants': 1380004000}]]
└──iTree['America', data=iTData[{'surface': 42549000, 'inhabitants': 1009000000}]]
└──iTree['Canada', data=iTData[{'surface': 9984670, 'inhabitants': 38008005}]]
└──iTree['Mexico', data=iTData[{'surface': 1972550, 'inhabitants': 127600000}]]
└──iTree['Australia&Oceania', data=iTData[{'surface': 8600000, 'inhabitants': 36000000}]]
└──iTree['Australia', data=iTData[{'surface': 7688287, 'inhabitants': 25700000}]]
└──iTree['New Zealand', data=iTData[{'surface': 269652, 'inhabitants': 4900000}]]
└──iTree['Europe', data=iTData[{'surface': 10523000, 'inhabitants': 746000000}]]
└──iTree['France', data=iTData[{'surface': 632733, 'inhabitants': 67400000}]]
└──iTree['Finland', data=iTData[{'surface': 338465, 'inhabitants': 5536146}]]
└──iTree['Antarktika', data=iTData[{'surface': 14000000, 'inhabitants': 1100}]]
E.g. Filtering can be done like this:
>>>item_filter = Filter.iTFilterData[data_key='inhabitants', data_value=iTInterval[0, 20000000]]
>>>iterator=root.iter_all[item_filter=item_filter]
>>>for i in iterator:
>>> print[i]
iTree["'New Zealand'", data=iTData[{'surface': 269652, 'inhabitants': 4900000}], subtree=[]]
iTree["'Finland'", data=iTData[{'surface': 338465, 'inhabitants': 5536146}], subtree=[]]
iTree["'Antarktika'", data=iTData[{'surface': 14000000, 'inhabitants': 1100}], subtree=[]]
Trees are non-linear data structures that represent nodes connected by edges. Each tree consists of a root node as the Parent node, and the left node and right node as Child nodes.
Binary tree
A tree whose elements have at most two children is called a binary tree. Each element in a binary tree can have only two children. A node’s left child must have a value less than its parent’s value, and the node’s right child must have a value greater than its parent value.
%0 node_127 node_214 node_1->node_2 node_335 node_1->node_3 node_159309474347810 node_2->node_1593094743478 node_15930947425849 node_2->node_1593094742584 node_159309480342531 node_3->node_1593094803425 node_159309477358442 node_3->node_1593094773584
Implementation
Here we have created a node
class and assigned a value to the node.
# node class
class Node:
def __init__[self, data]:
# left child
self.left = None
# right child
self.right = None
# node's value
self.data = data
# print function
def PrintTree[self]:
print[self.data]
root = Node[27]
root.PrintTree[]
The above code will create node 27 as parent node.
Insertion
The insert
method compares the value of the node to the parent node and decides whether to add it as a left node or right node.
Remember: if the node is greater than the parent node, it is inserted as a right node; otherwise, it’s inserted left.
Finally, the PrintTree
method is used to print the
tree.
class Node:
def __init__[self, data]:
self.left = None
self.right = None
self.data = data
def insert[self, data]:
# Compare the new value with the parent node
if self.data:
if data < self.data:
if self.left is None:
self.left = Node[data]
else:
self.left.insert[data]
elif data > self.data:
if self.right is None:
self.right = Node[data]
else:
self.right.insert[data]
else:
self.data = data
# Print the tree
def PrintTree[self]:
if self.left:
self.left.PrintTree[]
print[ self.data],
if self.right:
self.right.PrintTree[]
# Use the insert method to add nodes
root = Node[27]
root.insert[14]
root.insert[35]
root.insert[31]
root.insert[10]
root.insert[19]
root.PrintTree[]
The above code will create root node as 27, left child as 14, and right child as 35.
Searching
While searching for a value in the tree, we need to traverse the node from left to right and with a parent.
class Node:
def __init__[self, data]:
self.left = None
self.right = None
self.data = data
# Insert method to create nodes
def insert[self, data]:
if self.data:
if data < self.data:
if self.left is None:
self.left = Node[data]
else:
self.left.insert[data]
elif data > self.data:
if self.right is None:
self.right = Node[data]
else:
self.right.insert[data]
else:
self.data = data
# findval method to compare the value with nodes
def findval[self, lkpval]:
if lkpval < self.data:
if self.left is None:
return str[lkpval]+" is not Found"
return self.left.findval[lkpval]
elif lkpval > self.data:
if self.right is None:
return str[lkpval]+" is not Found"
return self.right.findval[lkpval]
else:
return str[self.data] + " is found"
# Print the tree
def PrintTree[self]:
if self.left:
self.left.PrintTree[]
print[self.data],
if self.right:
self.right.PrintTree[]
root = Node[27]
root.insert[14]
root.insert[35]
root.insert[31]
root.insert[10]
root.insert[19]
print[root.findval[7]]
print[root.findval[14]]
Here it creates tree 10 19 14 27 31 35 nodes. In this tree 7 nodes is not there so it gives the output as 7 not found. 14 is the left child root.
RELATED TAGS
binary tree
create node
insert a node
search a node
communitycreator