-1

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"
}
martineau
  • 99,260
  • 22
  • 139
  • 249
corode
  • 3
  • 3
  • 1
    Welcome! Have you tried anything yourself to achieve this? Can you share this with us? Are there specific problems you are having with getting your code working? We'd like to help you to be a better programmer rather than just doing work for you. The aim of this forum is not to write code for people, but rather to help discuss specific coding issues and aid the asker and those who come along in the future with a better understanding of the languages and the tools involved. – CryptoFool Aug 30 '20 at 14:59
  • Yes, I have tried searching for various ways of implementing this. Before, I was using anytree to try and create a hierarchy which I could export in this format, however, my code became very complex so I took a different angle and created this list hierarchy. I have found ways that I can use this list itself to store values and how to improve that system here: https://stackoverflow.com/questions/635483/what-is-the-best-way-to-implement-nested-dictionaries. However, I am using a bootstrap hierarchy template so that format did not work - the template needs the specific format mentioned above. – corode Aug 30 '20 at 15:08

2 Answers2

0

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"
    }
]
CryptoFool
  • 15,463
  • 4
  • 16
  • 36
0

Please try below code. call it with modify(input)

Code

def modify(input):
    return [{"text":key,"nodes":modify(value) if isinstance(value,dict) else value} if value else {"text":key} for key,value in input.items()]
    

Input

input={'Parent 1': {'Child 1': {'Grandchild 1': {}, 'Grandchild 2': {}}, 'Child 2': {}}, 'Parent 2': {}}

Output

[
  {
    "text": "Parent 1",
    "nodes": [
      {
        "text": "Child 1",
        "nodes": [
          {
            "text": "Grandchild 1"
          },
          {
            "text": "Grandchild 2"
          }
        ]
      },
      {
        "text": "Child 2"
      }
    ]
  },
  {
    "text": "Parent 2"
  }
]

Note: This uses recursion

Liju
  • 1,799
  • 2
  • 3
  • 16