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 children

    class 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": []
    }
    ]
    }
    ]
    }




Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2