Stefan - 1 year ago 152
Python Question

# Python merge dictionaries with custom merge function

I want to merge two dictionaries A and B such that the result contains:

• All pairs from A where key is unique to A

• All pairs from B where key is unique to B

• f(valueA, valueB) where the same key exists in both A and B

For example:

``````def f(x, y):
return x * y

A = {1:1, 2:3}
B = {7:3, 2:2}

C = merge(A, B)
``````

Output:

``````{1:1, 7:3, 2:6}
``````

It feels like there should be a nice one-liner to do this.

Use dictionary views to achieve this; the `dict.viewkeys()` result acts like a set and let you do intersections and symmetrical differences:

``````def merge(A, B, f):
# Start with symmetric difference; keys either in A or B, but not both
merged = {k: A.get(k, B.get(k)) for k in A.viewkeys() ^ B.viewkeys()}
# Update with `f()` applied to the intersection
merged.update({k: f(A[k], B[k]) for k in A.viewkeys() & B.viewkeys()})
return merged
``````

In Python 3, the `.viewkeys()` method has been renamed to `.keys()`, replacing the old `.keys()` functionality (which in Python 2 returs a list).

The above `merge()` method is the generic solution which works for any given `f()`.

Demo:

``````>>> def f(x, y):
...     return x * y
...
>>> A = {1:1, 2:3}
>>> B = {7:3, 2:2}
>>> merge(A, B, f)
{1: 1, 2: 6, 7: 3}
>>> merge(A, B, lambda a, b: '{} merged with {}'.format(a, b))
{1: 1, 2: '3 merged with 2', 7: 3}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download