How to merge dictionaries of dictionaries?

后端 未结 29 3212
渐次进展
渐次进展 2020-11-22 05:13

I need to merge multiple dictionaries, here\'s what I have for instance:

dict1 = {1:{\"a\":{A}}, 2:{\"b\":{B}}}

dict2 = {2:{\"c\":{C}}, 3:{\"d\":{D}}
         


        
29条回答
  •  一个人的身影
    2020-11-22 06:14

    I had two dictionaries (a and b) which could each contain any number of nested dictionaries. I wanted to recursively merge them, with b taking precedence over a.

    Considering the nested dictionaries as trees, what I wanted was:

    • To update a so that every path to every leaf in b would be represented in a
    • To overwrite subtrees of a if a leaf is found in the corresponding path in b
      • Maintain the invariant that all b leaf nodes remain leafs.

    The existing answers were a little complicated for my taste and left some details on the shelf. I hacked together the following, which passes unit tests for my data set.

      def merge_map(a, b):
        if not isinstance(a, dict) or not isinstance(b, dict):
          return b
    
        for key in b.keys():
          a[key] = merge_map(a[key], b[key]) if key in a else b[key]
        return a
    

    Example (formatted for clarity):

     a = {
        1 : {'a': 'red', 
             'b': {'blue': 'fish', 'yellow': 'bear' },
             'c': { 'orange': 'dog'},
        },
        2 : {'d': 'green'},
        3: 'e'
      }
    
      b = {
        1 : {'b': 'white'},
        2 : {'d': 'black'},
        3: 'e'
      }
    
    
      >>> merge_map(a, b)
      {1: {'a': 'red', 
           'b': 'white',
           'c': {'orange': 'dog'},},
       2: {'d': 'black'},
       3: 'e'}
    

    The paths in b that needed to be maintained were:

    • 1 -> 'b' -> 'white'
    • 2 -> 'd' -> 'black'
    • 3 -> 'e'.

    a had the unique and non-conflicting paths of:

    • 1 -> 'a' -> 'red'
    • 1 -> 'c' -> 'orange' -> 'dog'

    so they are still represented in the merged map.

提交回复
热议问题