nb123
nb123

Reputation: 84

How can I recursively modify the keys and values of a nested dictionary?

So I have a nested dictionary of arbitrary depth that is similar to this:

sample_dict = {
    'root_node': {
        'child_1': {
            'child_1a': {
                'child_1a_a': {},
                'child_1a_b': {},
                ...,
                'child_1a_x': {}
            },
            'child_1b': {
                'child_1b_a': {
                    'child_1b_a_a': {},
                    'child_1b_a_b': {},
                    ...
                },
                'child_1b_b': {
                    'child_1b_b_a': {},
                    ...
                },
                'child_1b_c': {}
            }
        },
        'child_2': {
                ...
            }
        }
    }

I need to convert the above dictionary into something like this:

sample_dict_output = {
    'title':'root_node',
    'key':'root_node',
    'children':[
        { 'title':'child_1',
          'key':'child_1',
          'children':[
              {'title':'child_1a',
               'key':'child_1a',
               'children':[
                 {'title': 'child_1a_a',
                  'key': 'child_1a_a'},
                 {'title': 'child_1a_b',
                  'key': 'child_1a_b'},
                   ...
                 {'title': 'child_1a_x',
                  'key': 'child_1a_x'},
               ],},
              {'title':'child_1b',
               'key':'child_1b',
               'children':[
                 {'title': 'child_1b_a',
                  'key': 'child_1b_a',
                  'children':[
                      {'title': 'child_1b_a_a',
                       'key': 'child_1b_a_a'},
                      {'title': 'child_1b_a_b',
                       'key': 'child_1b_a_b'},
                      ...
                  ],},
                 {'title': 'child_1b_b',
                  'key': 'child_1b_b',
                   'children':[
                    {'title': 'child_1b_b_a',
                     'key': 'child_1b_b_a'},
                    ...,
                 ],},
                {'title': 'child_1b_c',
                 'key': 'child_1b_c'}
                ],
              },
        { 'title':'child_2',
          'key':'child_2',
          'children':[...]
        }
    ],
}

I tried to search Stackoverflow for a solution and also attempted recursion, but to no avail. Hence, any help would be appreciated (preferably in Python 3.x). Thank you!

Upvotes: 0

Views: 358

Answers (1)

user2390182
user2390182

Reputation: 73460

The following will get you in the right direction:

def convert_item(key, val):
    conv = {
        "title": key, 
        "key": key, 
    }
    if val:
        conv["children"] = convert_dict(val)
    return conv

def convert_dict(dct):
    return [
        convert_item(k, v) for k, v in dct.items()
    ]

>>> convert_dict(sample_dict)[0]
{
    "title": "root_node",
    "key": "root_node",
    "children": [
        {
            "title": "child_1",
            "key": "child_1",
            "children": [
                {
                    "title": "child_1a",
                    "key": "child_1a",
                    "children": [
                        {"title": "child_1a_a", "key": "child_1a_a"},
                        {"title": "child_1a_b", "key": "child_1a_b"},
                        {"title": "child_1a_x", "key": "child_1a_x"},
                    ],
                },
                {
                    "title": "child_1b",
                    "key": "child_1b",
                    "children": [
                        {
                            "title": "child_1b_a",
                            "key": "child_1b_a",
                            "children": [
                                {"title": "child_1b_a_a", "key": "child_1b_a_a"},
                                {"title": "child_1b_a_b", "key": "child_1b_a_b"},
                            ],
                        },
                        {
                            "title": "child_1b_b",
                            "key": "child_1b_b",
                            "children": [
                                {"title": "child_1b_b_a", "key": "child_1b_b_a"}
                            ],
                        },
                        {"title": "child_1b_c", "key": "child_1b_c"},
                    ],
                },
            ],
        }
    ],
}

Or with a single recursive function:

def convert_dict(dct):
    return [
        {"title": k, "key": k, **({"children": convert_dict(v)} if v else {})}
        for k, v in dct.items()
    ]

Upvotes: 1

Related Questions