Reputation: 4774
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.
Upvotes: 0
Views: 4344
Reputation: 4033
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
Upvotes: 0
Reputation: 1091
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.
Upvotes: 2