如何更新字典而不添加新键?

19 投票
3 回答
8970 浏览
提问于 2025-04-17 16:16

有什么好的一行代码(除了把它放进一个函数里)来实现这个呢:

# like dict1.update(dict2) but does not add any keys from dict2
# that are not already in dict1
for k in dict1:
    if k in dict2:
        dict1[k]=dict2[k]

我想这个方法可以用,但它使用了一个“受保护”的函数:

[dict1.__setitem__(k, dict2[k]) for k in dict1 if k in dict2]

3 个回答

1

使用 map/zip

可以分成两行写,这样更容易看:

match_keys = dict1.keys() & dict2.keys()
dict2.update(**dict(zip(match_keys, map(dict2.get, match_keys))))

或者可以写成一行:

dict2.update(**dict(zip(dict1.keys() & dict2.keys(), map(dict2.get, dict1.keys() & dict2.keys()))))

不破坏原有数据:

new_dict = {**dict2, **dict(zip(dict1.keys() & dict2.keys(), map(dict2.get, dict1.keys() & dict2.keys())))}
4

非破坏性地:

dict((k, dict2.get(k, v)) for k, v in dict1.items())

修改 dict1

dict1.update((k, v) for k, v in dict2.items() if k in dict1)
28
dict1.update((k, dict2[k]) for k in set(dict2).intersection(dict1))

这是我在 Python 2.6 或更早版本中处理这个问题的方法(稍后会介绍在更新版本中如何做)。

除了另一个映射,dict.update() 还可以接受一个包含 (键, 值) 元组的可迭代对象,我们是根据两个字典的交集来生成这些元组的(也就是说,它们共有的所有键)。

演示:

>>> dict1 = {'foo':'bar', 'ham': 'eggs'}
>>> dict2 = {'ham': 'spam', 'bar': 'baz'}
>>> dict1.update((k, dict2[k]) for k in set(dict2).intersection(dict1))
>>> dict1
{'foo': 'bar', 'ham': 'spam'}

在 Python 2.7 中,你可以使用新的 字典视图 来实现相同的功能,而不需要转换为集合:

dict1.update((k, dict2[k]) for k in dict1.viewkeys() & dict2.viewkeys())

在 Python 3 中,字典视图是默认的,所以你可以这样写:

dict1.update((k, dict2[k]) for k in dict1.keys() & dict2.keys())

撰写回答