How to create a hierarchical data storage class
-
Got a list. How do you keep this in class?
input= [ (None, 'a'), (None, 'b'), (None, 'c'), ('a', 'a1'), ('a', 'a2'), ('a2', 'a21'), ('a2', 'a22'), ('b', 'b1'), ('b1', 'b11'), ('b11', 'b111'), ('b', 'b2'), ('c', 'c1'), ]
It's like a class. I don't know how to get a parent element.
class Node(object): def __init__(self): self.children = []
def add_child(self, obj): self.children.append(obj)
-
Added the name, parent, introduced a specific knot - the root element
In filling the elements, a dictionary was used to facilitate the search for elements
To test the structure ' s performance, a method was used
Node.print
and all of its childrenclass Node: def __init__(self, name: str, parent: 'Node' = None): self.name = name self.parent = parent self.children = []
def add_child(self, obj: 'Node'): self.children.append(obj) @property def parent_name(self) -> str: return self.parent.name if self.parent else None def __repr__(self) -> str: return f'Node(name={self.name!r}, parent={self.parent_name!r}, children_len={len(self.children)})' def print(self): def _print(node: Node, level=0): print(' ' * level + f'{node.name} ({len(node.children)})') for child in node.children: _print(child, level + 1) _print(self)
source = [
(None, 'a'),
(None, 'b'),
(None, 'c'),
('a', 'a1'),
('a', 'a2'),
('a2', 'a21'),
('a2', 'a22'),
('b', 'b1'),
('b1', 'b11'),
('b11', 'b111'),
('b', 'b2'),
('c', 'c1'),
]name_by_node = dict()
name_by_node[None] = Node('ROOT', None)for parent, child in source:
parent_node = name_by_node[parent]
if child not in name_by_node:
name_by_node[child] = Node(child, parent_node)parent_node.add_child(name_by_node[child])
name_by_node[None].print()
Recurring conclusion:
ROOT (3)
a (2)
a1 (0)
a2 (2)
a21 (0)
a22 (0)
b (2)
b1 (1)
b11 (1)
b111 (0)
b2 (0)
c (1)
c1 (0)
UPD.
To generate the dictionary, a method should be added:
def to_dict(self) -> dict:
def _to_dict(node: Node):
return {
'name': node.name,
'parent': node.parent_name,
'children': [_to_dict(child) for child in node.children],
}return _to_dict(self)
Call (for ease in json):
data = name_by_node[None].to_dict()
print(json.dumps(data, indent=4, ensure_ascii=False))
Result:
{
"name": "ROOT",
"parent": null,
"children": [
{
"name": "a",
"parent": "ROOT",
"children": [
{
"name": "a1",
"parent": "a",
"children": []
},
{
"name": "a2",
"parent": "a",
"children": [
{
"name": "a21",
"parent": "a2",
"children": []
},
{
"name": "a22",
"parent": "a2",
"children": []
}
]
}
]
},
{
"name": "b",
"parent": "ROOT",
"children": [
{
"name": "b1",
"parent": "b",
"children": [
{
"name": "b11",
"parent": "b1",
"children": [
{
"name": "b111",
"parent": "b11",
"children": []
}
]
}
]
},
{
"name": "b2",
"parent": "b",
"children": []
}
]
},
{
"name": "c",
"parent": "ROOT",
"children": [
{
"name": "c1",
"parent": "c",
"children": []
}
]
}
]
}