Как объединить два словаря в один в Python?
У меня два словаря с настройками, хочу слить их в один. Видел разные способы: update(), оператор |, распаковку через **. Чем они отличаются и что произойдёт, если в обоих словарях есть одинаковый ключ?
2 ответа
В Python 3.9+ самый чистый способ — оператор |:
a = {'x': 1, 'y': 2}
b = {'y': 99, 'z': 3}
merged = a | b # {'x': 1, 'y': 99, 'z': 3}
При конфликте ключей побеждает правый словарь — поэтому y стал 99. Создаётся новый словарь, оба исходных не меняются.
До 3.9 (и сейчас тоже работает) — распаковка через **:
merged = {**a, **b}
Правило то же: значения из b перекрывают a.
Если нужно изменить первый словарь, а не создавать новый — update():
a.update(b) # теперь a == {'x': 1, 'y': 99, 'z': 3}
Разница в одном: | и {**a, **b} возвращают новый словарь, а update() правит a на месте и возвращает None.
Главная ловушка — порядок. Если хотите, чтобы при конфликте побеждали значения из a, ставьте его справа: b | a. И не пишите a = a.update(b) — получите None.
Для слияния «в глубину» (когда значения сами словари и их надо объединять рекурсивно) встроенных средств нет — пишите функцию вручную.
Если надо слить много словарей разом, удобно через ChainMap или цикл:
from collections import ChainMap
merged = dict(ChainMap(c, b, a))
У ChainMap приоритет, наоборот, у первого словаря, поэтому порядок аргументов обратный привычному. Если путаетесь — проще явный цикл: result = {}; for d in [a, b, c]: result.update(d). Тут побеждает последний, как и у update.