Reputation: 1360
I have a nested dictionary and I want to update the value of an item based on its key value. For example, I have the following dictionary and I want to set the value of every occurrence of an item with key=='p' to be 1.
my_dict = {'p': 0, 'nested_dict': {'p': 0, 'a': 2}}
For a regular dictionary (non-nested) the update method provides a simple one-liner solution:
my_dict.update((x, 1) for x, y in my_dict.items() if x=='p')
I'm looking for a similar solution for the case of nested dictionary
Upvotes: 2
Views: 344
Reputation: 15204
If the max depth of the dictionary is known and constant and the 'p'
s always appear at the same depth this can be solved without recursion. In all other cases, a recursive approach is needed. Based on the example problem and your comments, I will assume that the second one is true. Here is a recursive solution:
def setPto1(dct):
return {k: setPto1(v) if isinstance(v, dict) else [v, 1][k=='p'] for k, v in dct.items()}
So you basically loop through the key-value pairs with a recursive dictionary comprehension. You were not far off with your approach. If there is something you do not understand about it, leave a comment.
If [v, 1][k=='p']
makes you feel uneasy, you can replace it with the more straight-forward (1 if k=='p' else v)
. They are the same thing.
Upvotes: 2
Reputation: 1432
Maybe this could get you started (you can still make it more generic, and it might have problems with repeated keys):
from functools import reduce
def decision_func(d, item, replace_on_item, replace_val):
if item == replace_on_item:
d[item] = replace_val
else:
return d[item]
my_dict = {'p': 0, 'nested_dict': {'p': 0, 'a': 2}}
reduce(lambda d, item: decision_func(d, item, 'p', ["some_other_val", 2]), ['nested_dict', 'p'], my_dict)
print(my_dict)
Output:
{'p': 0, 'nested_dict': {'p': ['some_other_val', 2], 'a': 2}}
What is done here is that you are going to run down the nesting tree by using the reduce
function, and the decision_func
is the one making the decision on whether to update a given entry or return the value for that key and continue looking for the next nesting level (basically a recursion prob). Note that as written above, this is not yet a bullet proof implementation.
Upvotes: 0