how to convert add another level to nested dictionary which has a tuple as a key in python

Question:

There is a nested dictionary whose second level key is in tuples such as:

dic1={'a': {('a', 'b'): ['c','d'],
    ('a', 'c'): ['d','f','g'],
    ('c', 'k'): ['f','h'],
    ('c', 'j'): [], 
    ('h', 'z'): ['w']
}}

I would like to convert the tuple keys at the second level into other level of key so that the nested dictionary looks like as

{
    'a':
    {
        'a':
        {
            'b': ['c', 'd'],
            'c': ['d', 'f', 'g']
        },
        'c':
        {
            'k': ['f', 'h'],
            'j': []
        },
        'h':
        {
            'z': ['w']
        }
    }
}

I have tried the code below but I cannot get the expected result

dic2 = {k:[i[0] for i in v] for k,v in dic1.items()}

Thanks in advance.

Asked By: H_H

||

Answers:

After observing the problem description, it seems that the structure of the data provided by OP is very fixed (and more general recursive structure have many limitations, because it is necessary to avoid that the deepest value is both a dictionary and a list), so the recursive scheme is abandoned here and the loop is hard coded:

def make_nested(mp):
    res = {}
    for k, v in mp.items():
        res[k] = new_val = {}
        for (vk1, vk2), vv in v.items():
            new_val.setdefault(vk1, {})[vk2] = vv
    return res

Test:

>>> mapping
{'a': {('a', 'b'): ['c', 'd'],
       ('a', 'c'): ['d', 'f', 'g'],
       ('c', 'k'): ['f', 'h'],
       ('c', 'j'): [],
       ('h', 'z'): ['w']}}
>>> make_nested(mapping)
{'a': {'a': {'b': ['c', 'd'], 'c': ['d', 'f', 'g']},
       'c': {'k': ['f', 'h'], 'j': []},
       'h': {'z': ['w']}}}
Answered By: Mechanic Pig
big_dic = {}
for k, v in dic1.items():
    big_dic[k] = {}
    for k1, v1 in v.items():
        big_dic[k][k1[0]] = {}
    for k1, v1 in v.items():
        big_dic[k][k1[0]][k1[1]] = v1
        
Answered By: Garrett Johnson
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.