2015-03-24 2 views
1

У меня есть два вложенных словаря, которые имеют перекрывающиеся клавиши на первом уровне, но разные клавиши на втором уровне. Я хочу объединить их, чтобы новый словарь имел все ключи.Как слить два вложенных словаря вместе?

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

Результат должен быть

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

Я знаю, что я мог бы сделать for петлю

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

Но я хотел бы знать, если есть чистое решение.

ответ

3

Вы можете объединить их в словаре понимания:

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

Это использует Python 2 dictionary keys view object; в Python 3 используйте dict.keys() вместо dict.viewkeys().

Это объединит все ключи, даже если они присутствуют только в одном или другом словарях.

Демо с входом:

>>> 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}} 

или с входом с более разнообразными ключами:

>>> 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'}} 
+0

Я незнаком с '' **. Что это делает? – Cecilia

+0

@ 2cents: он применяет ключи словаря в качестве аргументов ключевого слова. См. [Что делает \ * \ * (двойная звезда) и \ * (звезда) для параметров Python?] (Http://stackoverflow.com/q/36901). В этом случае тривиально объединить два словаря. –

1
  1. словаре Iterate B
  2. Проверьте, если ключ от B присутствует в A - Обработка исключений
  3. Если да, то обновите соответствующее значение A на B.
  4. Если нет, то добавить новый ключ со значением в A

код:

>>> 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}} 
>>> 
+0

Как это лучше, чем цикл for, который я привел в качестве примера? – Cecilia

+0

@ 2cents: Если 'B' имеет ключ, которого нет в' A', то это не будет выводиться. –

+0

@ 2cents: вы не обрабатываете исключение, если ключ отсутствует в ключе в 'A [key] .update (B [key])' statement. Это вызовет исключение KeyError. –

Смежные вопросы