Cecilia
Cecilia

Reputation: 4721

How can I merge two nested dictionaries together?

I've got two nested dictionaries that have overlapping keys at the first level, but different keys at the second level. I want to merge them, so that the new dictionary has all of the keys.

A = {'id1': {'key1': 1, 'key2': 2 }, 'id2':{'key1': 3, 'key2': 4 }}
B = {'id1': {'key3': 5}, 'id2': {'key3': 6}}

The result should be

A_B = {'id1': {'key1': 1, 'key2': 2, 'key3': 5}, 'id2':{'key1': 3, 'key2': 4, 'key3': 6}}

I know that I could do a for loop

for key in A:
    A[key].update(B[key])

But I would like to know if there is a cleaner solution.

Upvotes: 2

Views: 1096

Answers (2)

Vivek Sable
Vivek Sable

Reputation: 10213

  1. Iterate dictionary B
  2. Check if key from the B is present in the A- Exception Handling
  3. If yes, then Update respective value of A by B.
  4. If Not, then Add New Key with value in A

code:

>>> A = {'id1': {'key1': 1, 'key2': 2 }, 'id2':{'key1': 3, 'key2': 4 }}
>>> B = {'id1': {'key3': 5}, 'id2': {'key3': 6}}
>>> for i, j in B.items(): 
...      if i in A:
...          A[i].update(j)
...      else:
...          A[i] = j
... 
>>> A
{'id2': {'key3': 6, 'key2': 4, 'key1': 3}, 'id1': {'key3': 5, 'key2': 2, 'key1': 1}}
>>> 

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1121724

You could merge them in a dictionary comprehension:

A_B = {k: dict(A.get(k, {}), **B.get(k, {})) for k in A.viewkeys() | B.viewkeys()}

This uses the Python 2 dictionary keys view object; in Python 3, use dict.keys() instead of dict.viewkeys().

This'll merge all keys even if they are only present in one or the other of the dictionaries.

Demo with your input:

>>> A = {'id1': {'key1': 1, 'key2': 2 }, 'id2':{'key1': 3, 'key2': 4 }}
>>> B = {'id1': {'key3': 5}, 'id2': {'key3': 6}}
>>> {k: dict(A.get(k, {}), **B.get(k, {})) for k in A.viewkeys() | B.viewkeys()}
{'id2': {'key3': 6, 'key2': 4, 'key1': 3}, 'id1': {'key3': 5, 'key2': 2, 'key1': 1}}

or with input with more varied keys:

>>> C = {'foo': {'spam': 1, 'ham': 2}, 'bar': {'spam': 43, 'eggs': 81}}
>>> D = {'baz': {'vikings': 'singing'}, 'bar': {'monty': 'python'}}
>>> {k: dict(C.get(k, {}), **D.get(k, {})) for k in C.viewkeys() | D.viewkeys()}
{'bar': {'eggs': 81, 'monty': 'python', 'spam': 43}, 'foo': {'ham': 2, 'spam': 1}, 'baz': {'vikings': 'singing'}}

Upvotes: 3

Related Questions