Merging two dictionaries while keeping the original

If it's alright to keep all values as a list (which I would prefer, it just adds extra headache and logic when your value data types aren't consistent), you can use the below approach for your updated example using a defaultdict

from itertools import chain
from collections import defaultdict

d1 = {'a': 1, 'b': 2, 'c': 3}
d2 = {'a': 2, 'b': 3, 'd': 4}

d3 = defaultdict(list)

for k, v in chain(d1.items(), d2.items()):
    d3[k].append(v)

for k, v in d3.items():
    print(k, v)

Prints:

a [1, 2]
d [4]
c [3]
b [2, 3]

You also have the below approach, which I find a little less readable:

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

d3 = dict((k, [v] + ([d2[k]] if k in d2 else [])) for (k, v) in d1.items())

print(d3)

This wont modify any of the original dictionaries and print:

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

a = {'a': 1, 'b': 2, 'c': 3}
b = {'a': 10, 'd': 2, 'e': 3}

b.update({key: (a[key], b[key]) for key in set(a.keys()) & set(b.keys())})
b.update({key: a[key] for key in set(a.keys()) - set(b.keys())})

print(b)

Output: {'c': 3, 'd': 2, 'e': 3, 'b': 2, 'a': (1, 10)}