Быстрый однострочный
c = {**a, **b, **{key:min(a[key], b[key]) for key in set(a).intersection(set(b))} }
Объяснение
Это должно быть достаточно быстро, потому что он использует set
.
Вы можете объединять словари используя синтаксис **dictionary
, например: {**a, **b}
. **
просто «расширяет» словарь в каждый отдельный элемент, причем последний расширенный словарь перезаписывает все предыдущие (так, в {**a, **b}
, любые совпадающие ключи в b
перезаписывают значение из a
).
Первое, что я делаю, это загружаю все значения в a
и b
в новый словарь:
c = {**a, **b, ...
Затем я использую понимание словаря для создания нового словарь, который имеет наименьшее значение для каждого набора ключей, которые находятся в a
и b
.
... {key:min(a[key], b[key]) for key in set(a).intersection(set(b))} ...
Чтобы получить набор ключей, которые существуют только в a
и b
, я конвертирую оба словаря в set
s (что преобразует их в наборы их ключей) и использую intersection
, чтобы быстро найти все ключи, которые есть в обоих наборах.
... set(a).intersection(set(b)) ...
Затем я oop через каждый из ключей в наборе совпадающих ключей и использовать понимание словаря для создания нового словаря с текущим key
и min
значений обоих словарей для этого key
.
... {key:min(a[key], b[key]) ...
Чт Common crawl ru Я использую синтаксис **
, чтобы «расширить» этот новый сгенерированный словарь расширенными a
и b
, помещая его последним, чтобы убедиться, что он перезаписывает любые значения из двух.
Работает на приведен пример (ctrl-cv'd прямо с моего терминала):
>>> a = {1:14, 2:15, 3:16, 4:17}
>>> b = {2:19, 3:9, 4:11, 5:13}
>>> c = {**a, **b, **{key:min(a[key], b[key]) for key in set(a).intersection(set(b))} }
>>> c
{1: 14, 2: 15, 3: 9, 4: 11, 5: 13}