I'm trying to implement a tree with unique IDs per 'section' nodes and unique IDs for each child node in each section. I wonder how to accomplish this with anytree (python)
. I tried this:
from anytree import AnyNode, RenderTree, Resolver
class MyTree:
def create(self):
self.root = AnyNode(id="root")
initial_section_node = AnyNode(id="section1", parent=self.root)
AnyNode(id="sub0A", parent=initial_section_node)
AnyNode(id="sub0B", parent=initial_section_node)
another_section_node = AnyNode(id="section2", parent=self.root)
AnyNode(id="sub0A", parent=another_section_node)
AnyNode(id="sub0B", parent=another_section_node)
def add_node_to_parent(self, section_id, node_id: str):
r = Resolver("id")
section_node = r.get(self.root, section_id)
if node_id not in section_node.children:
AnyNode(id=node_id, parent=section_node)
else:
print(node_id + " already exists")
def display(self):
print(RenderTree(self.root))
test_tree = MyTree()
test_tree.create()
test_tree.add_node_to_parent("section1", "sub0C")
test_tree.add_node_to_parent("section1", "sub0A") # this will add another node with this id, but I want to prevent this
test_tree.display()
but it displays
AnyNode(id='root')
├── AnyNode(id='section1')
│ ├── AnyNode(id='sub0A')
│ ├── AnyNode(id='sub0B')
│ ├── AnyNode(id='sub0C')
│ └── AnyNode(id='sub0A')
└── AnyNode(id='section2')
├── AnyNode(id='sub0A')
└── AnyNode(id='sub0B')
i.e., I can use the resolver to find the right section and then add new nodes to it, but the condition if node_id not in section_node.children:
does not work because node_id
is not a node object but a string object.
I understand that I need using the resolver once again to check if there is a child node of the "section1" node with the ID I want to add, but I would prefer using the collection section_node.children
instead, because I think it works faster than the resolver, especially for big trees.
As you said, you cannot directly check for inclusion of a
string
in atuple
ofobjects
. You may define a function, e.g.But I doubt this can be faster than
Resolver
.Alternatively you may handle a custom attribute
children_ids
, and use that for your check.