How to add values dynamically to nested dicts?

Viewed 320

I want to add a value to a specific key within a nested dict, I have no idea how I could make that possible. So I have a:

thedict = {'one': {'two': {'three': {'four': None}}}}

and I want to add a value to four, or add another key/value pair to one:

thedict['one']['two']['three']['four'] = thevalue
thedict['one']['new'] = 'something else'

That is possible that way. But how can I make this more dynamic? For example, I have a list in this context:

thedict = {'one': {'two': {'three': {'four': None}}}}
thelist = ['one', 'two', 'three', 'four']
thevalue = 'something'

How can I then assign thevalue to four? Of course, thedict and thelist are dynamically created, I can't just do:

thedict[thelist[0]][thelist[1]][thelist[2]][thelist[3]] = thevalue
5 Answers

You can do

thedict = {'one': {'two': {'three': {'four': None}}}}
thelist = ['one', 'two', 'three', 'four']
thevalue = 'something'

curr = thedict
for idx, k in enumerate(thelist):
    if idx == len(thelist) - 1:
        curr[k] = thevalue
    else:
        curr = curr[k]
print(thedict)

You could loop through the keys until you reach the innermost dict, then set the value:

# Loop until inner dict
subdict = thedict
for key in thelist[:-1]:
    subdict = subdict.get(key)

# Set value
subdict[thelist[-1]] = thevalue

Here's a recursive way to do it:

import pprint

thedict = {'one': {'two': {'three': {'four': None}}}}
thelist = ['one', 'two', 'three', 'four']
thevalue = 'something'

def assign_by_path(d, l, v):
    if len(l) == 1:
        d[l[0]] = v
    else:
        assign_by_path(d[l[0]], l[1:], v)

pprint.pprint(thedict) 
==> {'one': {'two': {'three': {'four': None}}}}


assign_by_path(thedict, thelist, thevalue)
pprint.pprint(thedict)

==> {'one': {'two': {'three': {'four': 'something'}}}}

I seems like you want to create a tree that can be accessed through a path and hold values. If that is the case each node of the tree must be able to hold a value and a branch. This however would mean that you would need a structure slightly different than what you have right now.

You can use a for loop to locate the None in your dictionary and put your new key.

Will be something like this:

for key, value in thedict.values():
    if value is None:
        thedict[key] = new_dict
Related