I tried to implement a tree data structure in Python. This is what I've ended up so far:
class Node:
"""
This class implements a node in a tree.
# Arguments #
metadata:dict=dict() | A dict to store metadata.
subnodes:tuple=tuple() | A tuple to define subnodes.
"""
def __init__(self, metadata={"label": None, "content": None, "description": None}, subnodes=list()):
self.metadata = metadata
self.subnodes = subnodes
def __str__(self):
return "[{label}] {content}".format(
label=str(self["label"]),
content=str(self["content"])
)
def __repr__(self):
return "<{}>".format(str(self))
def __len__(self):
count = len(self.subnodes)
for n in self.subnodes:
print(n)
count+=len(n.subnodes)
return count
def __contains__(self, o):
# check if in subnodes of self
if o in self.subnodes:
return True
# check if in subnodes (recursive)
for n in self.subnodes:
if o in n:
return True
return False
def __getitem__(self, key):
return self.metadata[key]
def __setitem__(self, key, value):
self.metadata[key] = value
def __delitem__(self, key):
del self.metadata[key]
def __lt__(self, o):
return self in o
def __gt__(self, o):
return o in self
def append(self, o:"Node"):
"""
Appends an object as children.
# Arguments #
o:Node | Node object.
"""
self.subnodes.append(o)
def insert(self, i:int, o:"Node"):
"""
Inserts an object to given index.
# Arguments #
i:int | Index
o:Node | Node object
"""
self.subnodes.insert(i, o)
def remove(self, o:"Node"):
"""
Removes an object from subnodes.
# Arguments #
o:Node | Node object
"""
self.subnodes.remove(o)
def is_leafnode(self):
"""
Is this node a leaf node?
"""
return len(self) == 0
def search(self, **query):
"""
Searches tree with metadata.
**query:dict | Searching query.
"""
return [d for d in self.metadata if all(d.get(k, object()) == v for k, v in query.items())]
I add subnodes by append
function of a Node
object. However, subnodes
attribute acts as if it was a static attribute.
What I expect is:
However, subnodes
attribute of all objects returns:
Manual Test
I have tested it by hand. I have 6 Node
objects as below:
- a
- b
- c
- d
- e
- f
I wanted to achieve a structure as I demonstrated above. So I made:
a.append(b) # a => b
a.append(c) # a => c
b.append(d) # b => d
b.append(e) # b => e
c.append(f) # c => f
However, when I call subnodes
attribute of any Node
object:
a.subnodes # [<[b] None>, <[c] None>, <[d] None>, <[e] None>, <[f] None>]
b.subnodes # [<[b] None>, <[c] None>, <[d] None>, <[e] None>, <[f] None>]
# ...
# rest is the same
Environment
- Python 3.5.1