Home > Mobile >  How to fill nested dict when you only have a list of key, value for the final layers?
How to fill nested dict when you only have a list of key, value for the final layers?

Time:07-06

I have a nested dict of the folling form:

dict1 = {layer1: {layer2: {layer3: {a:None, b:None, c:None}}, {d:None, e:None}}}

And a flat dict with only the values in the final layer:

dict2 = {a:1, b:2, c:3, d:4, e:5}

My expected output after filling the values in the first dict would be:

dict_out = {layer1: {layer2: {layer3: {a:1, b:2, c:3}}, {d:4, e:5}}}

How should I approach this?

CodePudding user response:

I hope I've understood your question correctly. You can use recursion to replace the values of keys in-place:

dct = {
    "layer1": {
        "layer2": {"layer3": {"a": 0, "b": 0, "c": 0}},
        "layer4": {"d": 0, "e": 0},
    }
}

dct2 = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}


def replace(d):
    if isinstance(d, dict):
        for k in d & dct2.keys():
            d[k] = dct2[k]

        for k in d - dct2.keys():
            replace(d[k])

    elif isinstance(d, list):
        for i in d:
            replace(i)


replace(dct)
print(dct)

Prints:

{
    "layer1": {
        "layer2": {"layer3": {"a": 1, "b": 2, "c": 3}},
        "layer4": {"d": 4, "e": 5},
    }
}

CodePudding user response:

Another approach using recursion, you really only need one written loop. I find this easier to decipher. It also doesn't alter the original dict inplace:

data = {"layer1": {"layer2": {"layer3": {"a": None, "b": None, "c": None}, "layer4": {"d": None, "e": None}}}}
values = {"a": 1, "b": 2, "c": 3, "d": 4, "e": 5}

def fill_data(data):
    out = {}

    for key, value in data.items():
        if isinstance(value, dict):
            out[key] = fill_data(value)
        else:
            out[key] = values.get(key, value)

    return out

print(fill_data(data))

{'layer1': {'layer2': {'layer3': {'a': 1, 'b': 2, 'c': 3}, 'layer4': {'d': 4, 'e': 5}}}}
  • Related