I have an arbitrarily deep set of nested dictionary:
x = {'a': 1, 'b': {'c': 6, 'd': 7, 'g': {'h': 3, 'i': 9}}, 'e': {'f': 3}}
and I'd like to basically apply a function to all the integers in the dictionaries, so like map
, I guess, but for nested dictionaries.
So: map_nested_dicts(x, lambda v: v + 7)
would be the sort of goal.
I'm stuck as to the best way to perhaps store the layers of keys to then put the modified value back into its correct position.
What would the best way/approach to do this be?
Use a dictionary comprehension to map a function over all values in a dictionary. Use the syntax {key: f(value) for key, value in dict. items()} to apply the function f to each value in the dictionary dict .
Adding elements to a Nested Dictionary One way to add a dictionary in the Nested dictionary is to add values one be one, Nested_dict[dict][key] = 'value'.
Access Values using get() Another way to access value(s) in a nested dictionary ( employees ) is to use the dict. get() method. This method returns the value for a specified key. If the specified key does not exist, the get() method returns None (preventing a KeyError ).
The technique is when you have a python dictionary and a function that you intend to use on it. You insert an extra element into the dict, whose value is the name of the function. When you're ready to call the function you issue the call indirectly by referring to the dict element, not the function by name.
Visit all nested values recursively:
import collections
def map_nested_dicts(ob, func):
if isinstance(ob, collections.Mapping):
return {k: map_nested_dicts(v, func) for k, v in ob.iteritems()}
else:
return func(ob)
map_nested_dicts(x, lambda v: v + 7)
# Creates a new dict object:
# {'a': 8, 'b': {'c': 13, 'g': {'h': 10, 'i': 16}, 'd': 14}, 'e': {'f': 10}}
In some cases it's desired to modify the original dict object (to avoid re-creating it):
import collections
def map_nested_dicts_modify(ob, func):
for k, v in ob.iteritems():
if isinstance(v, collections.Mapping):
map_nested_dicts_modify(v, func)
else:
ob[k] = func(v)
map_nested_dicts_modify(x, lambda v: v + 7)
# x is now
# {'a': 8, 'b': {'c': 13, 'g': {'h': 10, 'i': 16}, 'd': 14}, 'e': {'f': 10}}
If you're using Python 3:
replace dict.iteritems
with dict.items
replace import collections
with import collections.abc
replace collections.Mapping
with collections.abc.Mapping
If you need it to work for both lists and dicts in arbitrary nesting:
def apply_recursive(func, obj):
if isinstance(obj, dict): # if dict, apply to each key
return {k: apply_recursive(func, v) for k, v in obj.items()}
elif isinstance(obj, list): # if list, apply to each element
return [apply_recursive(func, elem) for elem in obj]
else:
return func(obj)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With