【问题标题】:Merge a dict in Python using 1 dict as base [duplicate]使用1个字典作为基础在Python中合并一个字典[重复]
【发布时间】:2018-01-04 14:03:33
【问题描述】:

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

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

  • 应该添加仅存在于其他字典中的键
  • 应考虑嵌套字典

我写了这个简单的函数:

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

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

【问题讨论】:

  • 如果对应的key不在base_dict中,则不会添加other_dict的值。这是想要的行为吗?
  • 所以other_dict 中不在base_dict 中的键应该被忽略,对吧?
  • 这个问题不是重复的,至少不是那些问题;这里嵌套的dicts 必须考虑在内。
  • 是的,不应该添加额外的键。这是想要的行为。
  • 是的,嵌套字典确实必须考虑在内。

标签: python dictionary nested


【解决方案1】:

“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}}

【讨论】:

  • 这里的一个很好的问题是“if other_dict is None”,但你为什么不使用:“if not other_dict”?
  • @user1934514 老实说,我假设other_dict 永远不会包含None,我不确定这是否适合您的情况。但是,我猜 0False""[] 是太有效的值,所以我避免丢弃它们 is None 而不是只检查它的“虚假”值(None 值应该当k 不存在时,来自堆栈中上一次调用中的other_dict.get(k))。
  • 解决这个问题的一种方法是使用“个人标记”来检测丢失的键。 marker = object(),那么 if 将是 if other_dict is not marker: ,您必须将标记作为默认值传递给 get 方法 merge_dicts(v, other_dict.get(k, marker))
【解决方案2】:

如果您使用的是 python 3.5 或更高版本,您可以这样做:

merged_dict = {**base_dict, **other_dict}

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

merged_dict = {}
merged_dict.update(base_dict)
merged_dict.update(other_dict)

有关它的更多信息,您可以查看The Idiomatic Way to Merge Dictionaries in Python

【讨论】:

  • 这不考虑嵌套的dicts。
猜你喜欢
  • 2019-06-19
  • 2021-11-05
  • 2012-09-12
  • 2018-10-16
  • 2018-04-16
  • 2019-01-05
  • 2012-05-20
  • 1970-01-01
  • 2021-03-13
相关资源
最近更新 更多