Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python nested dictionary update value where any nested key matches

I have a nested dictionary where every element can be of any type including a list or dictionary. I'm looking for a method to update any key at any depth with a particular value. (So the replacement occurs if the target value is not a list or dictionary)

e.g

{
   'a': 1,
   'b': 2,
   'c': [{'a': 2, 'b': 3}],
   'd': [{'d_d': {'a': 1, 'b': 2}}],
   'e': {'a': 4},
}

would become

{
   'a': 'xx',
   'b': 2,
   'c': [{'a': 'xx', 'b': 3}],
   'd': [{'d_d': {'a': 'xx', 'b': 2}}],
   'e': {'a': 'xx'},
}

where the function takes a dictionary, key and new value like so

update_nested(dict, key='a', value='xx')
like image 923
taina Avatar asked Apr 13 '26 08:04

taina


1 Answers

Let's look at which parts you need and how to implement them:

iterate over a dictionary

there are three different methods that help you to iterate over a dictionary:

dict.keys()

iterating over all keys in the dict. e.g.

for key in {"Hello": 10, "World", 20}.keys():
   print(k)
# output: Hello\nWorld

dict.items()

iterating over all (key, value) tuples in the dict. for k, v in d.items()

dict.values()

iterating over all values in the dict. for v in d.values()

Handle nested dictionaries

When you have nested structures a good concept would recursion

In short: You call the same function in itself with different parameters.

putting both concepts together.

  • Iterate over the array
  • If the key is the same as the one you are searching for: Replace the value
  • If the value is a dict: Call the function again with the value as dict parameter
  • If the value is a list: Iterate over all items and check if they are dicts. If so handle them like above

Possible final code:

def update_nested(in_dict, key, value):
   for k, v in in_dict.items():
       if key == k:
           in_dict[k] = value
       elif isinstance(v, dict):
           update_nested(v, key, value)
       elif isinstance(v, list):
           for o in v:
               if isinstance(o, dict):
                   update_nested(o, key, value)

Extra note:

You should never use a builtin name/type as a variable name. In your case dict. This will override the builtin type and can lead to unexpected behavior.

like image 146
Uli Sotschok Avatar answered Apr 14 '26 21:04

Uli Sotschok