在Python中使用1个dict作为基合并dict

在Python中使用1个dict作为基合并dict,python,dictionary,nested,Python,Dictionary,Nested,我正在寻找关于我的Python代码的反馈。我正试图合并两本词典。其中一个字典控制结构和默认值,第二个字典将在适用时覆盖默认值 请注意,我正在寻找以下行为: 仅存在于其他dict中的键不应添加 应该考虑嵌套的dict 我编写了这个简单的函数: def merge_dicts(base_dict, other_dict): """ Merge two dicts Ensure that the base_dict remains as is and overwrite info

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

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

  • 仅存在于其他dict中的键不应添加
  • 应该考虑嵌套的dict
我编写了这个简单的函数:

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。

如果您使用的是python 3.5或更高版本,您只需执行以下操作:

merged_dict = {**base_dict, **other_dict}
如果您使用的是以前的任何版本,您可以使用
update
方法:

merged_dict = {}
merged_dict.update(base_dict)
merged_dict.update(other_dict)
有关它的更多信息,您可以查看“Pythonicness”是一个很难评估的指标,但以下是我对它的看法:

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()}
例如:

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

如果相应的键不在
base\u dict
中,则不会添加
other\u dict
的值。这是想要的行为吗?所以
other_dict
中不在
base_dict
中的键应该被忽略,对吗?这个问题不是重复的,至少不是那些问题;这里必须考虑嵌套的
dict
s。是的,不应添加额外的键。这就是想要的行为。是的,嵌套的dict确实必须考虑在内。这并不能解释嵌套的
dict
s。这里的一个好习惯是“if other dict is None”,但是为什么不使用:“if nother other dict”?@user1934514老实说,我假设
other dict
永远不会包含
None
,我不确定这对你的案子是否有好处。但是,我想
0
False
[]
都是太有效的值,所以我避免丢弃它们
是无的
,而不是只检查它的“falsy”值(
None
值应该来自
其他dict.get(k)当
k
不存在时,在堆栈中的上一个调用中执行
)。解决此问题的一种方法是使用“个人标记”来检测丢失的密钥
marker=object()
,如果其他dict不是marker:
则if将是
,并且必须将该标记作为默认值传递给get方法
merge\u dict(v,其他dict.get(k,marker))