# Add 100 to all values in nested dictionary

I want to change all values in a multidimensional dictionary. I have written this line of code, which does what I want it to do and I am trying to find out if this is the optimal way or just some convoluted solution I came up with:

 dict_data = dict([x,dict([y, dict_data[x][y]+100] for y in dict_data[x])] for x in dict_data)


If you're using both keys and values from a dictionary, then using the items method:

... for key, val in dct.items() ...


is neater than iterating over the keys and including dct[key] everywhere. In Python 2.7+, you can use a dictionary comprehension (see e.g. the tutorial) rather than pass a list comprehension to dict:

dict_data = {key: {key_: val_+100 for key_, val_ in val.items()}
for key, val in dict_data.items()}


Note that using key, val and the _ versions also makes it clearer what's happening than x and y.

• You forgot to use items... – Stefan Pochmann May 11 '15 at 17:06
• @StefanPochmann oh, for pity's... thank you! – jonrsharpe May 11 '15 at 17:07
• You forgot it in the inner comprehension as well. C'mon, give up trying to fit it in one line :-P – Stefan Pochmann May 11 '15 at 17:11
• Seeing it written with key and value i can easily see how this becomes more readable. Thanks for the explanations! – Guest20150511 May 12 '15 at 7:19

With comprehensions, which I generally love, I'd do it like jonrsharpe did. But here I'd find a loop much clearer:

for inner in dict_data.values():
for key in inner:
inner[key] += 100


Both can also be generalized to something more complex than a strictly two-dimensional dictionary, and again I find the loop version clearer (though less so):

def loop_add(dict_data):
for inner in dict_data.values():
for key in inner:
inner[key] += 100

# copied from jonrsharpe
return {key: {key_: val_+100 for key_, val_ in val.items()}
for key, val in dict_data.items()}

for key, value in dict_data.items():
if isinstance(value, dict):
else:
dict_data[key] += 100

return {key: rec_comp_add(value) if isinstance(value, dict) else value+100
for key, value in dict_data.items()}


A little speed test with the above functions and a 10x10 dictionary:

dict_data = {x: {y: x*y+10000000 for y in range(10)} for x in range(10)}
import copy, timeit
cloned = copy.deepcopy(dict_data)
seconds = timeit.timeit(lambda:func(cloned), number=100000)
print('%6.3f seconds' % seconds, func.__name__)


Output:

 3.579 seconds loop_add

 3.160 seconds loop_add