如何更新字典而不添加新键?
有什么好的一行代码(除了把它放进一个函数里)来实现这个呢:
# 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())