itamar kanter
itamar kanter

Reputation: 1360

update values in nested dict based on key

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

Answers (2)

Ma0
Ma0

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

deponovo
deponovo

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

Related Questions