'Update dict without adding new keys?
What is a good 1-liner (other than putting this into a function) to achieve this:
# 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]
I guess that this would work, but uses a "protected" function:
[dict1.__setitem__(k, dict2[k]) for k in dict1 if k in dict2]
Solution 1:[1]
dict1.update((k, dict2[k]) for k in set(dict2).intersection(dict1))
is how I'd do it in Python 2.6 or below (see further on how to do this in later versions).
Next to another mapping, dict.update() can also take an iterable of (key, value) tuples, which we generate based on the set intersection of the two dictionaries (so all keys they have in common).
Demo:
>>> 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'}
In python 2.7 you can use the new Dict views to achieve the same without casting to sets:
dict1.update((k, dict2[k]) for k in dict1.viewkeys() & dict2.viewkeys())
In Python 3, dict views are the default, so you can instead spell this as:
dict1.update((k, dict2[k]) for k in dict1.keys() & dict2.keys())
Solution 2:[2]
Non-destructively:
dict((k, dict2.get(k, v)) for k, v in dict1.items())
Modifying dict1:
dict1.update((k, v) for k, v in dict2.items() if k in dict1)
Solution 3:[3]
Using map/zip As two lines for readability:
match_keys = dict1.keys() & dict2.keys()
dict2.update(**dict(zip(match_keys, map(dict2.get, match_keys))))
Or as a one-liner:
dict2.update(**dict(zip(dict1.keys() & dict2.keys(), map(dict2.get, dict1.keys() & dict2.keys()))))
non-destrctively:
new_dict = {**dict2, **dict(zip(dict1.keys() & dict2.keys(), map(dict2.get, dict1.keys() & dict2.keys())))}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | ecatmur |
| Solution 3 | Ryan |
