I am new to python and I was looking for a way to convert the following dictionary into a format that is outlined below it using some code.
{'Parent 1': {'Child 1': {Grandchild 1: {}, 'Grandchild 2: {}}, 'Child 2': {}} Parent 2: {}}
And then convert this to:
{
'text': "Parent 1",
'nodes': [
{
'text': "Child 1",
'nodes': [
{
'text': "Grandchild 1"
},
{
'text': "Grandchild 2"
}
]
},
{
'text': "Child 2"
}
]
},
{
'text': "Parent 2"
}
Maybe I shouldn't make it so easy, but I'll give you the answer. Two of them actually. Please study these so that you learn something. If this is homework or something, don't just submit the answer without learning from it.
A first approach would be to solve the problem without recursion. You just follow the problem through from level to level, doing what you need to do to read the original data structure and and produce the new structure:
data = {'Parent 1': {'Child 1': {'Grandchild 1': {}, 'Grandchild 2': {}}, 'Child 2': {}}, 'Parent 2': {}}
parent_nodes = []
for parent_text, parent_data in data.items():
parent_entry = {'text': parent_text}
child_nodes = []
for child_text, child_data in parent_data.items():
child_entry = { 'text': child_text }
grandchild_nodes = []
for grandchild_text, grandchild_data in child_data.items():
grandchild_entry = { 'text': grandchild_text }
grandchild_nodes.append(grandchild_entry)
if len(grandchild_nodes):
child_entry['nodes'] = grandchild_nodes
child_nodes.append(child_entry)
if len(child_nodes):
parent_entry['nodes'] = child_nodes
parent_nodes.append(parent_entry)
print(json.dumps(parent_nodes, indent=4))
As you become a better programmer, you'll learn to recognize patterns that will allow you to reduce the size of your code and make it more general. In this case, you may recognize that this problem is about a data structure that has multiple levels that follow the same pattern. You should be able to write code that could handle not just three levels, but 4, 5 or 100 levels.
The way to do this is with recursion. You recognize that you need to process a lower level first, and then you can complete the processing of a higher level. In processing the lower level, you recognize the same thing again, so again you process the lower level first. This is recursion. Here's code that also does what you want, but with recursion:
data = {'Parent 1': {'Child 1': {'Grandchild 1': {}, 'Grandchild 2': {}}, 'Child 2': {}}, 'Parent 2': {}}
def do_one_level(data):
nodes = []
for text, entry in data.items():
node = { 'text': text }
subnode = do_one_level(entry)
if len(subnode):
node['nodes'] = subnode
nodes.append(node)
return nodes
parent_nodes = do_one_level(data)
print(json.dumps(parent_nodes, indent=4))
Notice that the do_one_level()
function calls itself. This is recursion. Keep in mind that the reason that this second version is "better" is not just that it is less code, but more importantly that it can handle any number of levels in the input data structure.
Both versions produce the same output:
[
{
"text": "Parent 1",
"nodes": [
{
"text": "Child 1",
"nodes": [
{
"text": "Grandchild 1"
},
{
"text": "Grandchild 2"
}
]
},
{
"text": "Child 2"
}
]
},
{
"text": "Parent 2"
}
]