Merging two dictionaries while keeping both the original and the new value for each key

Viewed 5478

In Python, when I merge two dictionaries using the update() method, any existing keys will be overwritten.

Is there a way to merge the two dictionaries while keeping the original keys in the merged result?

Say we had the following example:

dict1 = {'bookA': 1, 'bookB': 2, 'bookC': 3}
dict2 = {'bookC': 2, 'bookD': 4, 'bookE': 5}

Can we merge the two dictionaries, such that the result will keep both values for the key bookC?

I'd like dict3 to look like this:

{'bookA': 1, 'bookB': 2, 'bookC': (2,3), 'bookD': 4, 'bookE': 5}
5 Answers

There is another way to keep all values as a list, which is not using defaultdict or chain.

Revise the example:

d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'a': 2, 'b': 3, 'd': 4}
d3 = {}
for (k, v) in list(d1.items())+list(d2.items()):
    try:
        d3[k] += [v]
    except KeyError:
        d3[k] = [v]
print(d3)

Then we have:

{'d': [4], 'b': [2, 3], 'a': [1, 2], 'c': [3]}

The try statement is used for speed. It tries to add the value v with the key k. In case of KeyError, d3 accepts the new key.

If you care about the ordering which I think the other answers don't quite get right. This is Python 3.9:

dict1 = {'bookA': 1, 'bookB': 2, 'bookC': 3}
dict2 = {'bookC': 2, 'bookD': 4, 'bookE': 5}
dict3 = dict1 | dict2
dict4 = {key for key in dict1 if key in dict2}
dict5 = {key: (dict1[key], dict2[key]) for key in dict4}
result = dict3 | dict5

for item in result:
    print(repr(result[item]))

print(result)


1
2
(3, 2)
4
5
{'bookA': 1, 'bookB': 2, 'bookC': (3, 2), 'bookD': 4, 'bookE': 5}

You can then use tuple unpacking:

for item in result:
    if  type(result[item]) is tuple:
        print("Value from dict1: {}, value from dict2: {}".format(*result[item]))

Value from dict1: 3, value from dict2: 2

And if you want to be crazy and put the result dict on one line:

dict1 = {'bookA': 1, 'bookB': 2, 'bookC': 3}
dict2 = {'bookC': 2, 'bookD': 4, 'bookE': 5}

result = dict1 | dict2 | {key: (dict1[key], dict2[key]) for key in {key for key in dict1 if key in dict2}}
Related