dictionary:使用1个dict作为基础合并Python中的dict

本问题已经有最佳答案,请猛点这里访问。

我正在寻找关于我的Python代码的反馈。我正试图合并两本词典。其中一个字典控制结构和默认值,第二个字典将在适用时覆盖默认值。

请注意,我正在寻找以下行为:

不应添加仅出现在其他dict中的键应考虑到嵌套词

我写了这个简单的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def merge_dicts(base_dict, other_dict):
   """ Merge two dicts

    Ensure that the base_dict remains as is and overwrite info from other_dict
   """

    out_dict = dict()
    for key, value in base_dict.items():
        if key not in other_dict:
            # simply use the base
            nvalue = value
        elif isinstance(other_dict[key], type(value)):
            if isinstance(value, type({})):
                # a new dict myst be recursively merged
                nvalue = merge_dicts(value, other_dict[key])
            else:
                # use the others' value
                nvalue = other_dict[key]
        else:
            # error due to difference of type
            raise TypeError('The type of key {} should be {} (currently is {})'.format(
                key,
                type(value),
                type(other_dict[key]))
            )
        out_dict[key] = nvalue
    return out_dict

我相信这可以做得更漂亮/python。


"勾股定理"是一个很难评估的指标,但我的看法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
def merge_dicts(base_dict, other_dict):
   """ Merge two dicts

    Ensure that the base_dict remains as is and overwrite info from other_dict
   """

    if other_dict is None:
        return base_dict
    t = type(base_dict)
    if type(other_dict) != t:
        raise TypeError("Mismatching types: {} and {}."
                        .format(t, type(other_dict)))
    if not issubclass(t, dict):
        return other_dict
    return {k: merge_dicts(v, other_dict.get(k)) for k, v in base_dict.items()}

例子:

1
2
merge_dicts({"a":2,"b":{"b1": 5,"b2": 7}}, {"b": {"b1": 9}})
>>> {'a': 2, 'b': {'b1': 9, 'b2': 7}}


如果您使用的是python 3.5或更高版本,您可以简单地:

1
merged_dict = {**base_dict, **other_dict}

如果你使用任何以前的版本,你可以用update方法:

1
2
3
merged_dict = {}
merged_dict.update(base_dict)
merged_dict.update(other_dict)

有关它的更多信息,您可以检查Python中合并字典的惯用方法


您可以使用dict.update方法,以及一个生成器表达式:

1
base_dict.update((k, v) for k, v in other_dict.items() if k in base_dict)

解释

base_dict.update(other_dict)将用other_dict中的值覆盖base_dict中的值。如果一个键存在于other_dict而不在base_dict中,那么它将被添加到base_dict中,这不是您想要的。因此,您需要测试other_dict中的每个键是否在base_dict中。

dict.update可以将iterable作为第一个参数。如果后者包含2元组(k, v),则将base_dict[k]设置为v

摘要从help(dict.update):

update(...) method of builtins.dict instance

If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v

因此,将生成器表达式传递给它很方便。如果您不熟悉生成器表达式,括号内的内容或多或少相当于以下内容:

1
2
3
4
l = []
for k, v in other.dict_items():
    if k in base_dict:
        l.append((k, v))

然后l被传递给update,就像base_dict.update(l)一样。