-1

This is a follow up to following question on SO:

Access nested dictionary items via a list of keys?

All the solutions given in the above link allows to replace/create a value of the nested dict via a list of keys. But my requirement is to append (update) another dict to value.

If my dict is as follows:

dataDict = {
    "a":{
        "r": 1,
        "s": 2,
        "t": 3
        },
    "b":{
        "u": 1,
        "v": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "w": 3
        }
}   

And my list of keys is as follows:

maplist = ["b", "v"]

How can I append another dict, say "somevalue": {} to the dataDict['b']['v'] using my maplist?

So, after appending new dataDict would look as follows:

dataDict = {
        "a":{
            "r": 1,
            "s": 2,
            "t": 3
            },
        "b":{
            "u": 1,
            "v": {
                "x": 1,
                "y": 2,
                "z": 3,
                "somevalue": {}
            },
            "w": 3
            }
    }  

The solutions on the aforementioned SO link changes/creates the value like this:

dataDict[mapList[-1]] = value

But we can't call the dict's update function like dataDict[mapList[-1]].update().

Checked all of SO and Google, but no luck. Could someone please provide some help with this. Thanks!

Vivek Singh
  • 346
  • 3
  • 14

2 Answers2

3

This should work for you:

def set_item(this_dict, maplist, key, value):
    for k in maplist:
        if k not in this_dict:
            this_dict[k] = {}
        this_dict = this_dict[k]

    this_dict[key] = value

dataDict = {
    "a":{
        "r": 1,
        "s": 2,
        "t": 3
        },
    "b":{
        "u": 1,
        "v": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "w": 3
        }
}

maplist = ["b", "v"]
new_key = "somevalue"
new_value = {}

set_item(dataDict, maplist, new_key, new_value)

print(dataDict)

Output:

{'a': {'r': 1, 's': 2, 't': 3}, 'b': {'u': 1, 'v': {'x': 1, 'y': 2, 'z': 3, 'somevalue': {}}, 'w': 3}}
Ed Ward
  • 2,333
  • 2
  • 10
  • 16
2

You can use setdefault() method.

>>>dataDict['b']['v'].setdefault('something',{})
>>>print(dataDict)
{'a': {'r': 1, 's': 2, 't': 3}, 
'b': {'u': 1, 'v': {'x': 1, 'y': 2, 'z': 3, 'something': {}}, 
'w': 3}}

The above is the idea of how it works. Make a function for the above.

def set_new_key(d:dict,x:list,y:str):
    for key in x:
        d=d[key]
    d.setdefault(y,{})

dataDict = {
    "a":{
        "r": 1,
        "s": 2,
        "t": 3
        },
    "b":{
        "u": 1,
        "v": {
            "x": 1,
            "y": 2,
            "z": 3
        },
        "w": 3
        }
}

mapList=['b','v']
set_new_key(dataDict,mapList,'something')
print(dataDict)
print()
set_new_key(dataDict,['a'],'another')
print(dataDict)
print()
set_new_key(dataDict,['b','v','something'],'inside something')
print(dataDict)

output:

{'a': {'r': 1, 's': 2, 't': 3}, 'b': {'u': 1, 'v': {'x': 1, 'y': 2, 'z': 3, 'something': {}}, 'w': 3}}

{'a': {'r': 1, 's': 2, 't': 3, 'another': {}}, 'b': {'u': 1, 'v': {'x': 1, 'y': 2, 'z': 3, 'something': {}}, 'w': 3}}

{'a': {'r': 1, 's': 2, 't': 3, 'another': {}}, 'b': {'u': 1, 'v': {'x': 1, 'y': 2, 'z': 3, 'something': {'inside something': {}}}, 'w': 3}}
Ch3steR
  • 20,090
  • 4
  • 28
  • 58
  • Thanks Ch3steR! But this is not useful for my scenario because I need to update the dict dynamically using the list of keys in another function. – Vivek Singh Dec 30 '19 at 17:55
  • @VivekSingh check the edited answer. btw it was dynamic from the start. – Ch3steR Dec 30 '19 at 18:08