通过更新而不是覆盖合并字典中已存在的值

67 投票
9 回答
101480 浏览
提问于 2025-04-16 19:35

假设我有两个字典,内容如下:

d1 = {'a': 2, 'b': 4}
d2 = {'a': 2, 'b': ''}

如果我想把它们“合并”在一起,可以这样做:

dict(d1.items() + d2.items())

合并后得到的结果是:

{'a': 2, 'b': ''}

但是,如果我想比较这两个字典里的每个值,并且只在d1里的值是空的、None或者是空字符串''的时候,才把d2的值更新到d1,我该怎么做呢?

当同一个键在两个字典中都存在时,我希望只保留数字值(可以是d1的值,也可以是d2的值),而不是空值。如果两个值都是空的,那就保持空值没问题。如果两个都有值,那么d1的值应该保留。

比如:

d1 = {'a': 2, 'b': 8, 'c': ''}
d2 = {'a': 2, 'b': '', 'c': ''}

最终应该得到的结果是:

{'a': 2, 'b': 8, 'c': ''}

在这里,8不会被''覆盖。

9 个回答

10

如果你想把 d1 中的键值对添加到 d2 中,但前提是这些键值对在 d2 中还不存在,并且不想覆盖 d2 中已经有的键值对,可以这样做:

temp = d2.copy()
d2.update(d1)
d2.update(temp)
30

这个代码的意思是:用 d1 中的键值对来更新 d2,但前提是 d1 中的值不能是 None 或者空字符串(也就是 False)。

>>> d1 = dict(a=1, b=None, c=2)
>>> d2 = dict(a=None, b=2, c=1)
>>> d2.update({k: v for k, v in d1.items() if v})
>>> d2
{'a': 1, 'c': 2, 'b': 2}

(在 Python 2 中,使用 iteritems() 替代 items()。)

59

只需调换顺序:

z = dict(d2.items() + d1.items())

顺便提一下,你可能会对这个更快的 update 方法感兴趣。

在Python 3中,你需要先把视图对象转换成列表:

z = dict(list(d2.items()) + list(d1.items())) 

如果你想特别处理空字符串,可以这样做:

def mergeDictsOverwriteEmpty(d1, d2):
    res = d2.copy()
    for k,v in d2.items():
        if k not in d1 or d1[k] == '':
            res[k] = v
    return res

撰写回答