How to merge dictionaries of dictionaries?

后端 未结 29 2738
渐次进展
渐次进展 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

    One issue with this question is that the values of the dict can be arbitrarily complex pieces of data. Based upon these and other answers I came up with this code:

    class YamlReaderError(Exception):
        pass
    
    def data_merge(a, b):
        """merges b into a and return merged result
    
        NOTE: tuples and arbitrary objects are not handled as it is totally ambiguous what should happen"""
        key = None
        # ## debug output
        # sys.stderr.write("DEBUG: %s to %s\n" %(b,a))
        try:
            if a is None or isinstance(a, str) or isinstance(a, unicode) or isinstance(a, int) or isinstance(a, long) or isinstance(a, float):
                # border case for first run or if a is a primitive
                a = b
            elif isinstance(a, list):
                # lists can be only appended
                if isinstance(b, list):
                    # merge lists
                    a.extend(b)
                else:
                    # append to list
                    a.append(b)
            elif isinstance(a, dict):
                # dicts must be merged
                if isinstance(b, dict):
                    for key in b:
                        if key in a:
                            a[key] = data_merge(a[key], b[key])
                        else:
                            a[key] = b[key]
                else:
                    raise YamlReaderError('Cannot merge non-dict "%s" into dict "%s"' % (b, a))
            else:
                raise YamlReaderError('NOT IMPLEMENTED "%s" into "%s"' % (b, a))
        except TypeError, e:
            raise YamlReaderError('TypeError "%s" in key "%s" when merging "%s" into "%s"' % (e, key, b, a))
        return a
    

    My use case is merging YAML files where I only have to deal with a subset of possible data types. Hence I can ignore tuples and other objects. For me a sensible merge logic means

    • replace scalars
    • append lists
    • merge dicts by adding missing keys and updating existing keys

    Everything else and the unforeseens results in an error.

提交回复
热议问题