Modify the value of a multi-nested dictionary

Question:

What is the best way to access a multi-nested dictionary by its value and modify its value? The way that the value is modified must be by its current value. To explain better, the below example array myArr has a nested dictionary with value c2 how can I access that dictionary and modify c2 into c2_edit? The final output should look like editedArr. What is the most efficient way to achieve this for a large array size? Thanks in advance

myArr = [{
  "a1": [{
    "b1": "c1"
  }, {
    "b2": "c2"
  }]
}, {
  "a2": [{
    "b3": "c3"
  }, {
    "b4": "c4"
  }]
}]

#expected output
editedArr =  myArr = [{
  "a1": [{
    "b1": "c1"
  }, {
    "b2": "c2_edit"
  }]
}, {
  "a2": [{
    "b3": "c3"
  }, {
    "b4": "c4"
  }]
}]
Asked By: seriously

||

Answers:

The easiest way to modify an arbitrarily nested object is generally a recursive function:

>>> def recursive_replace(obj, old_value, new_value):
...     if obj == old_value:
...         return new_value
...     if isinstance(obj, dict):
...         return {k: recursive_replace(v, old_value, new_value) for k, v in obj.items()}
...     if isinstance(obj, list):
...         return [recursive_replace(i, old_value, new_value) for i in obj]
...     return obj
...
>>> myArr = [{
...   "a1": [{
...     "b1": "c1"
...   }, {
...     "b2": "c2"
...   }]
... }, {
...   "a2": [{
...     "b3": "c3"
...   }, {
...     "b4": "c4"
...   }]
... }]
>>> recursive_replace(myArr, "c2", "c2_edit")
[{'a1': [{'b1': 'c1'}, {'b2': 'c2_edit'}]}, {'a2': [{'b3': 'c3'}, {'b4': 'c4'}]}]

Other types of nested object (tuples, sets, or your own classes) can easily be added as additional if blocks in the replacement function. The important thing is that each recursive call needs to apply the function to the object’s contents and return the modified object.

Answered By: Samwise

Pythonic 1-liner function:

def edit_any_value(arr, val, n_val):
    return [{k: [{k: v if v != val else n_val for k, v in nd.items()} for nd in v]} for d in arr for k, v in d.items()]

This doesn’t modify the existing array, but it creates a new one with your modificated value.

I think creating new modified versions of one variable is always better than modifying it, but that’s just my opinion!

Answered By: RifloSnake
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.