Python: Apply function to values in nested dictionary

前端 未结 3 1426
我寻月下人不归
我寻月下人不归 2021-02-20 06:47

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}}
<
相关标签:
3条回答
  • 2021-02-20 07:07

    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)
    
    0 讨论(0)
  • 2021-02-20 07:14

    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

    0 讨论(0)
  • 2021-02-20 07:17

    Just to expand on vaultah's answer, if one of your elements can be a list, and you'd like to handle those too:

    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)
        elif isinstance(v, list):
            ob[k] = map(func, v)
        else:
            ob[k] = func(v)
    
    0 讨论(0)
提交回复
热议问题