Construct hierarchy tree from python flat parent-children dict list

北城余情 提交于 2019-12-12 03:26:20

问题


I have a dict list with the following structure:

[{
    "parent": "com.company.object.kind.type.subtype.family.Feline",
    "class": "com.company.object.kind.type.subtype.family.species.Cat"
}, {
    "parent": "com.company.object.kind.type.subtype.Mammal",
    "class": "com.company.object.kind.type.subtype.family.Feline"
}, {
    "parent": "com.company.object.Being",
    "class": "com.company.object.kind.LivingBeing"
}, {
    "parent": "com.company.object.kind.type.subtype.family.Canine",
    "class": "com.company.object.kind.type.subtype.family.species.Wolf"
}, {
    "parent": "com.company.object.kind.type.subtype.Mammal",
    "class": "com.company.object.kind.type.subtype.family.Canine"
}, {
    "parent": "com.company.object.kind.type.Animal",
    "class": "com.company.object.kind.type.subtype.Mammal"
}, {
    "parent": "com.company.object.kind.LivingBeing",
    "class": "com.company.object.kind.type.Animal"
}, {
    "parent": "com.company.object.kind.type.Animal",
    "class": "com.company.object.kind.type.subtype.Fish"
}, {
    "parent": "com.company.object.kind.StaticBeing",
    "class": "com.company.object.kind.type.Solid"
}, {
    "parent": "com.company.object.Being",
    "class": "com.company.object.kind.StaticBeing"
}, {
    "parent": "com.company.object.kind.type.subtype.family.Feline",
    "class": "com.company.object.kind.type.subtype.family.species.Lion"
}, {
    "parent": "com.company.object.kind.type.subtype.family.Canine",
    "class": "com.company.object.kind.type.subtype.family.species.Hyena"
}, {
    "parent": "com.company.object.kind.StaticBeing",
    "class": "com.company.object.kind.type.Liquid"
}]

And need to construct a hierarchy tree from it in the following way:

[
"com.company.object.Being" : [
        "com.company.object.kind.StaticBeing": [
            "com.company.object.kind.type.Solid",
            "com.company.object.kind.type.Liquid"
        ],
        "com.company.object.kind.LivingBeing": [
            "com.company.object.kind.type.Animal": [
                "com.company.object.kind.type.subtype.Fish",
                "com.company.object.kind.type.subtype.Mammal": [
                    "com.company.object.kind.type.subtype.family.Canine": [
                        "com.company.object.kind.type.subtype.family.species.Wolf",
                        "com.company.object.kind.type.subtype.family.species.Hyena"
                    ],
                    "com.company.object.kind.type.subtype.family.Feline": [
                        "com.company.object.kind.type.subtype.family.species.Lion",
                        "com.company.object.kind.type.subtype.family.species.Cat"
                    ]
                ]
            ]
        ]
    ]
]

The packages can be different and have any type of depth, it just only needs to construct the tree from the parent-child relationships.


回答1:


Here is a non-sophisticated way of doing this, looping through the list of objects three times, putting the tree nodes in a dictionary (treenodes) and the root node in root_node.

lst is the list provided in the question.

def display_node(node, indent=0):
    print ('.'*indent, node['class'])
    indent += 3
    for child in node['children']:
        display_node(child, indent)

# Create list of classes
classes = []
for item in lst:
    name = item['class']
    if name not in classes:
        classes.append(name)

treenodes = {}
root_node = None

for item in lst: # Create  tree nodes
    item['children'] = []
    name = item['class']
    treenodes[name] = item
    parent = item['parent']
    if parent not in classes: # parent is root node, create
        if parent not in treenodes:
            node = {}
            node['parent'] = None
            node['children'] = []
            node['class'] = parent
            root_node = node
            treenodes[parent] = node

# Connect parents and children
for item in lst: # Create  tree nodes
    parent = item['parent']
    parent_node = treenodes[parent]
    parent_node['children'].append(item)
display_node(root_node)

It might be better to create the nodes as objects and dispense with the treenodes dictionary. The process could have been achieved in one loop, but it might have been very complex.




回答2:


Notice you are mixing dictionaries and lists in your result. Assuming you want a dictionary with keys id and children then a recursive way to do it...

def build_tree(elems):
  elem_with_children = {}

  def _build_children_sub_tree(parent):
      cur_dict = {
          'id': parent,
          # put whatever attributes here
      }  
      if parent in elem_with_children.keys():
          cur_dict["children"] = [_build_children_sub_tree(cid) for cid in elem_with_children[parent]]
      return cur_dict

  for item in elems:
      cid = item['id']
      pid = item['parent']
      elem_with_children.setdefault(pid, []).append(cid)

  res = _build_children_sub_tree("com.company.object.Being")
  return res


来源:https://stackoverflow.com/questions/35452512/construct-hierarchy-tree-from-python-flat-parent-children-dict-list

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!