Содержание

Как объединить два словаря в Python

В этой статье мы рассмотрим различные способы объединения двух словарей в Python.

Содержание

  1. Введение
  2. Объединение словарей
  3. Объединение словарей в Python 3.9+
  4. Объединение словарей до Python 3.9
  5. Объединение словарей в Python 2
  6. Использование метода items()
  7. Использование метода update()
  8. Добавление значений списка во все версии Python
  9. Вывод

Введение

Часто бывают ситуации, когда в Python есть два словаря, которые вы хотели бы объединить.

Некоторые решения доступны не для всех версий Python, поэтому мы рассмотрим способы слияния для отдельных выпусков.

При объединении словарей мы должны учитывать что произойдет, если два словаря будут иметь одинаковые ключи. Давайте сначала определим, что должно произойти при слиянии словарей.

Объединение словарей

Слияния обычно происходят справа налево, так как dict_a <- dict_b.  Если в обоих словарях есть общий ключ, то значение второго словаря перезаписывает значение первого.

В этой статье мы будем использовать два словаря, а именно:

Словари со значениями

a = {1:'peanut', 2:'butter', 3:'jelly', 4:'time'}
b = {1:'fish', 2:'chips'}         

Словари с вложенными значениями

c = {1: ['peanut','butter','jelly','time'], 2:['fish','chips']} d = {1: ['fish','chips'], 2:['peanut','butter','jelly','time']}

Объединение словарей в Python 3.

9+

Начиная с версии Python 3.9, мы можем использовать операторов слияния (знак |) ставится для объединения двух словарей:

x = a | b print(x) {1: 'fish', 2: 'chips', 3: 'jelly', 4: 'time'}

Для слияния словарей также могут использоваться операторы, вместо вложенных словарей. Здесь происходит полная перезапись значения совпадающего ключа:

y = c | d
print(y)
 
{1: ['fish', 'chips'], 2: ['peanut', 'butter', 'jelly', 'time']}

Объединение словарей до Python 3.

9

К сожалению, на более ранних версий Python 3 мы не можем использовать операторов слияния. Но, вместо этого мы можем выполнить слияние, распаковав оба словаря, используя ** двойные звездочки, внутри другого словаря, как показано ниже:

x = {**a, **b}
print(x)
{1: 'fish', 2: 'chips', 3: 'jelly', 4: 'time'}

То же самое и со словарями со значениями вложенных списков. Значения дублирующихся ключей будут перезаписаны следующим образом:

y = {**c, **d}
print(y)
{1: ['fish', 'chips'], 2: ['peanut', 'butter', 'jelly', 'time']}

Объединение словарей в Python 2

В устаревших версиях Python приведенные выше фрагменты не будут работать.  В более поздних версиях слияние может быть облегчено путем объединения элементов словаря или dict_items обеих переменных.

Мы также можем использовать словарные методы copy() и update(). Включая этот, extend() он нам нужен для добавления его (данного словаря) в другой словарь.

Использование метода items()

Начнем с объединения с items():

x = dict(a.items() + b.items()) print(x) {1: 'fish', 2: 'chips', 3: 'jelly', 4: 'time'}

Приведенный выше синтаксис подходит для простых значений. Для вложенного словаря, содержащего значения списка, items() вызов необходимо преобразовать в list() а затем объединить:

y = dict(list(c. items()) + list(d.items())) print(y) {1: ['fish', 'chips'], 2: ['peanut', 'butter', 'jelly', 'time']}

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

Использование метода update()

Другой способ выполнить слияние — скопировать один из словарей и обновить его другим, как показано ниже:

x = a.copy() x.update(b) print (x) {1: 'fish', 2: 'chips', 3: 'jelly', 4: 'time'}

Добавление значений списка во все версии Python

В предыдущих разделах мы перезаписали вложенные значения объединенных словарей.  Бывают случаи, когда вложенные значения нужно добавлять, а не перезаписывать.

Это можно сделать, используя метод  

extend() показанный ниже:

for k, v in d.items():
    if k in c:
        c[k].extend(v)
    else:
        c[k] = v
print(c)
{1: ['peanut', 'butter', 'jelly', 'time', 'fish', 'chips'], 2: ['fish', 'chips', 'peanut', 'butter', 'jelly']}

Вывод

В этой статье мы узнали о том, как работает слияние словарей, и как мы можем объединить два словаря в разных версиях Python. Объединение словарей может быть очень удобным в таких ситуациях, как чтение нескольких файлов JSON, построение карты объектов или даже построение индексов контента.

11 способов как объединить два словаря в Python

Словарь Python – это структура данных, которая содержит все элементы в парах ключ-значение. Каждая пара “ключ-значение” сопоставляет ключи с их ассоциативным значением. Следовательно, он также известен как ассоциативный массив словаря Python. Все элементы словаря заключены в фигурные скобки {}. Кроме того, мы используем символ двоеточия(:) между парами ключ-значение, которые отделяют каждый ключ от его ассоциативного значения.

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

Объединение двух словарей с помощью цикла for

Здесь мы используем цикл For, который выполняет итерацию по первому словарю и одновременно добавляет записи в другой словарь для их объединения.

Рассмотрим программу для объединения заданных словарей с помощью цикла For.

forDict.py

 
dict1 = { 'Alexandra' : 27,      # given the first dictionary in key-value pairs 
            'Shelina Gomez' : 22, 
            'James' : 29, 
            'Peterson' : 30 
                        }  
dict2 = { 
            'Jasmine' : 19,      # given the second dictionary in key-value pairs 
            'Maria' : 26, 
            'Helena' : 30 
}                         
print("Before merging the two dictionary ") 
print("Dictionary No.
1 is : ", dict1) # print the dict1 print("Dictionary No. 1 is : ", dict2) # print the dict2 dict3 = dict1.copy() # Copy the dict1 into the dict3 using copy() method for key, value in dict2.items(): # use for loop to iterate dict2 into the dict3 dictionary dict3[key] = value print("After merging of the two Dictionary ") print(dict3) # print the merge dictionary

Выход:

Before merging the two dictionary 
Dictionary No. 1 is :  {'Alexandra': 27, 'Selina Gomez': 22, 'James': 29, 'Peterson': 30} 
Dictionary No. 1 is :  {'Jasmine': 19, 'Maria': 26, 'Helena': 30} 
After merging of the two Dictionary 
{'Alexandra': 27, 'Selina Gomez': 22, 'James': 29, 'Peterson': 30, 'Jasmine': 19, 'Maria': 26, 'Helena': 30} 

Соединение словарей с помощью метода update()

Метод update() используется в Python для обновления текущего словаря содержимым второго словаря. Используя метод update(), мы можем избежать создания третьего словаря для хранения первого элемента словаря и последующего обновления второго элемента словаря.

Рассмотрим программу для объединения заданных словарей на Python без создания третьего словаря.

Update1.py

 
d1 = {'Actress ' : 'Jasmine Wiley',      
    'Cricketer' : 'Nicholas Pooran', 
    'Basketball': 'Jordan', 
    'Football' : 'Zindane' 
} 
 
# Defines the d2 dictionary  
d2 = {'Tennis ' : 'Maria', 
    'Stadium  ' : 'Amsterdam', 
    'Basketball' : 'Washington', 
    'Actress' : 'Elizabeth'} 
 
d1.update(d2) # append the d2 dictionary items into the d1 dictionary. 
print( "Merge two dictionaries :") 
print(d1) # print the merge dictionary  

Выход:

{'Actress ': 'Jasmine Wiley', 'Cricketer': 'Nicholas Pooran', 'Basketball': 'Washington', 'Football': 'Zindane', 'Tennis ': 'Maria', 'Stadium  ': 'Amsterdam', 'Actress': 'Elizabeth'} 

Объединение с помощью функции

Давайте рассмотрим программу для объединения заданных словарей в Python с использованием метода update() в функции.

proFun.py

 
def merge_twoDict(a, b): # define the merge_twoDict() function 
    return(a.update(b)) # append the second dictionary(b) to the first dictionary(a)  
 
a = {'USA' : 'New York', 
      'Jermany' : 'Jakarta', 
      'England' : 'London' } 
b = { 
    'India' : 'Delhi', 
    'Russia' : 'Russian', 
    'Australia' : 'Sydney' 
}           
merge_twoDict(a, b) # pass two dictionaries to merge_twoDict() function 
print("Merged Dictionaries is : ") 
print(a) # print the merge dictionaries  

Выход:

Merged Dictionaries is : 
{'USA': 'New York', 'Germany': 'Jakarta', 'England': 'London', 'India': 'Delhi', 'Russia': 'Russian', 'Australia': 'Sydney'} 

Использование метода update(), когда оба словаря имеют одинаковые ключи

Давайте рассмотрим программу для объединения заданных словарей в Python с использованием метода update(), когда оба словаря содержат одинаковые ключи.

sameDict.py

 
# Defines the d1 dictionary in key- value pairs 
d1 = {     
    'Cricketer' : 'Nicholas Pooran', 
    'Basketball': 'Jordan', 
    'Football' : 'Zindane', 
    'Actress' : 'Jasmine Wiley'  
    } 
 
# Defines the d2 dictionary in key- value pairs 
d2 = { 'Tennis' : 'Maria', 
    'Stadium' : 'Amsterdam', 
    'Basketball' : 'Washington', 
    'Actress' : 'Elizabeth' } 
 
d1.update(d2) # append the d2 dictionary items into the d1 dictionary. 
print( "Merge two dictionaries :") 
print(d1) # print the merge dictionary 

Выход:

Merge two dictionaries : 
{'Cricketer': 'Nicholas Pooran', 'Basketball': 'Washington', 'Football': 'Zindane', 'Actress': 'Elizabeth', 'Tennis': 'Maria', 'Stadium': 'Amsterdam'} 

У нас есть два одинаковых ключа (Actress и Basketball) в обоих словарях. Когда мы выполняем метод обновления, последнее значение второго словаря переопределяет старые значения первого словаря. Когда словарь d1 выполняется, он печатает значения Washington и Elizabeth для ключей Actress и Basketball вместо Jasmine Wiley и Jordan.

С помощью метода Copy() и Update()

В этом методе мы копируем все элементы первого словаря(d1) с помощью функции copy(), а затем назначаем скопированные данные другому словарю(d3). После этого мы обновляем словарь d3 словарем d2 с помощью функции update().

Давайте рассмотрим программу для объединения заданных словарей с использованием методов copy и update() в Python.

CopyUpdate.py

 
dict1 = {            
    'Student' : 'Butler', 
    'Course' : 'Computer Science', 
    'Address' : 'Los Angeles' 
} 
 
 
dict2 = { 
    'Teacher' : 'Rosy', 
    'Subject' : 'Computer Science' 
} 
 
# Use Copy() function to copy the dict1 into the dict3 
dict3 = dict1.copy() 
print("Before Merge") 
print(dict3) # print dict3 dictionary 
 
# use update() dictionary function to update the dict3 using the dict2.  
dict3.update(dict2) 
 
print("After Merge of the two Dictionary is : ", dict3) 

Выход:

Before Merge 
{'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles'} 
After Merge of the two Dictionary is :  {'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles', 'Teacher': 'Rosy', 'Subject': 'Computer Science'} 

Объединение двух словарей с помощью оператора ** – оператора распаковки

Оператор распаковки, используемый для объединения двух или более словарей в одном выражении и сохранения их в третьем словаре.

Синтаксис:

 
Res = { **dictF1, ** dictF2 } 

Рассмотрим программу для объединения заданных словарей с помощью оператора ** в Python.

Распаковать.py

 
dict1 = {            
    'Student' : 'Butler', 
    'Course' : 'Computer Science', 
    'Address' : 'Los Angeles' 
} 
 
dict2 = { 
    'Teacher' : 'Rosy', 
    'Subject' : 'Computer Science' 
} 
 
dict3 = { 
    'Country' : 'England', 
    'State' : 'California', 
    'mob' : +3487434     
} 
 
# Use ** operator or Unpack Operator 
d5 = {**dict1, **dict2} 
print("Merge two dictionaries", d5) # Merge two dictionaries 
 
d4 = { 
    **dict1, **dict2, **dict3  
    } 
print("Merge more than two dictionaries", d4) # Merge multiples dictionaries 

Выход:

Merge two dictionaries {'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles', 'Teacher': 'Rosy', 'Subject': 'Computer Science'} 
Merge more than two dictionaries {'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles', 'Teacher': 'Rosy', 'Subject': 'Computer Science', 'Country': 'England', 'State': 'California', 'mob': 3487434} 

С помощью конструктора dict()

Метод конструктора dict() аналогичен методам copy() и update() в Словаре Python. Конструктор dict() копирует первые элементы словаря в новый словарь, а затем выполняет метод update(), чтобы обновить новый словарь вторым элементом словаря.

Давайте рассмотрим программу для объединения заданных словарей с помощью метода dict() в Python.

Dict.py

 
dict1 = {            
    'Student' : 'Butler', 
    'Course' : 'Computer Science', 
    'Address' : 'Los Angeles' 
} 
 
dict2 = { 
    'Teacher' : 'Rosy', 
    'Subject' : 'Computer Science' 
} 
 
# Use dict() constructor 
d3 = dict(dict1) 
print("Before Merge", d3) 
d3.update(dict2) 
print("Merge two dictionaries", d3) # Merge two dictionaries   

Выход:

Before Merge {'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles'} 
Merge two dictionaries {'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles', 'Teacher': 'Rosy', 'Subject': 'Computer Science'} 

Конструктор dict() и ** kwargs

Это сокращенный метод конструктора dict(), который использует оператор kwargs(**) для сопоставления одного словаря с другим с помощью метода dict().

Синтаксис:

 
D3 = dict(dict1, **dict) 

Рассмотрим программу для объединения двух словарей с помощью конструктора dict() и оператора ** kwargs в Python.

Kwarg.py

 
dict1 = {            
    'Student' : 'Butler', 
    'Course' : 'Computer Science', 
    'Address' : 'Los Angeles' 
} 
 
# Second dictionary is: 
dict2 = { 
    'Teacher' : 'Rosy', 
    'Subject' : 'Computer Science' 
} 
 
 
# Use dict() constructor 
d3 = dict(dict1, **dict2) 
 
print("Merge two dictionaries", d3) # Merge two dictionaries 

Выход:

Merge two dictionaries {'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles', 'Teacher': 'Rosy', 'Subject': 'Computer Science'} 

Используя функцию Collections – ChainMap

ChainMap – это набор из нескольких словарей, которые возвращают один словарь. Это более быстрый метод создания нового словаря и запуска нескольких файлов по сравнению с методом update(). Чтобы объединить два словаря в Python, нам нужно импортировать ChainMap из коллекций. В функции ChainMap() мы передаем два словаря в качестве аргумента, который возвращает экземпляры ChainMap для сопоставления словарей с помощью конструктора dict() для объединения словарей.

Давайте рассмотрим программу для объединения двух словарей с помощью функции ChainMap в Python.

Chain_map.py

 
dict1 = {            
    'Student' : 'Butler', 
    'Course' : 'Computer Science', 
    'Address' : 'Los Angeles' 
} 
dict2 = { 
    'Teacher' : 'Rosy', 
    'Subject' : 'Computer Science' 
} 
from collections import ChainMap  # import the ChainMap from collections 
 
# Use ChainMap() constructor 
d3 = dict(ChainMap(dict1, dict2)) # passes two parameters as an argument 
 
print("Merge two dictionaries", d3) # Merge two dictionaries 

Выход:

Merge two dictionaries {'Teacher': 'Rosy', 'Subject': 'Computer Science', 'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles'} 

Объединение словарей с помощью метода itertools – chain()

Он создает итеративный словарь, который возвращает элемент из первого итеративного словаря до его завершения. А затем он переходит к следующей итерации для дальнейшего выполнения в словаре. Следовательно, он представляет последовательные последовательности как единую последовательность.

Синтаксис:

 
itertools.chain( *iterables ) 

Давайте рассмотрим программу для объединения двух словарей с помощью функции цепочки в Python.

Chain.py

 
dict1 = {            
    'Student' : 'Butler', 
    'Course' : 'Computer Science', 
    'Address' : 'Los Angeles' 
} 
dict2 = { 
    'Teacher' : 'Rosy', 
    'Subject' : 'Computer Science' 
} 
from itertools import chain  # import the chain() function from itertools 
 
# Use ChainMap() constructor 
d3 = dict(chain(dict1.items(), dict2.items())) # passes two parameters as an argument 
 
print("Merge two dictionaries", d3) # Merge two dictionaries 

Выход:

Merge two dictionaries {'Student': 'Butler', 'Course': 'Computer Science', 'Address': 'Los Angeles', 'Teacher': 'Rosy', 'Subject': 'Computer Science'} 

Оператор слияния(|)

Оператор слияния(|) также используется для слияния двух словарей в Python. Python 3.9 представил оператор слияния(|) в классе dict.

Синтаксис:

 
dict1 |= dict2 

Напишем программу для объединения двух словарей на Python с помощью оператора слияния(|).

merge.py

 
def merge(dict1, dict): 
    result = dict1 | dict2 # use merge operator(|) 
    return result 
 
dict1 = {'A' : 'Apple', 'B' : 'Ball', 'C' : 'Cat' } # define dict1 
dict2 = {'D' : 'Dog', 'E' : 'Elephant', 'F' : 'Fish' } # define dict2 
dict3 = merge(dict1, dict2) # call merge() function 
print(dict3)    # print dict3 

Выход:

{'A': 'Apple', 'B': 'Ball', 'C': 'Cat', 'D': 'Dog', 'E': 'Elephant', 'F': 'Fish'} 

Михаил Русаков

Изучаю Python вместе с вами, читаю, собираю и записываю информацию опытных программистов.

Еще для изучения:

Словарь

— как объединить два словаря в одно выражение в Python?

Как объединить два словаря Python в одно выражение?

Для словарей x и y их неглубоко объединенный словарь z принимает значения из y , заменяя значения из x .

  • В Python 3.9.0 или более поздней версии (выпущен 17 октября 2020 г., PEP-584 , обсуждается здесь):

     г = х | у
     
  • В Python 3.5 или выше:

     г = {**х, **у}
     
  • В Python 2 (или 3.4 или ниже) напишите функцию:

     определение слияния_two_dicts (х, у):
        z = x.copy() # начать с ключей и значений x
        z.update(y) # изменяет z с ключами и значениями y
        вернуть Z
     

    и сейчас:

     z = merge_two_dicts(x, y)
     

Объяснение

Допустим, у вас есть два словаря, и вы хотите объединить их в новый словарь, не изменяя исходные словари:

 х = {'а': 1, 'б': 2}
у = {'б': 3, 'с': 4}
 

Желаемый результат — получить новый словарь ( z ) с объединенными значениями, а значения второго словаря перезаписывают значения из первого.

 >>> г
{'а': 1, 'б': 3, 'в': 4}
 

Новый синтаксис для этого, предложенный в PEP 448 и доступный в Python 3. 5,

 z = {**x, **y}
 

И это действительно одно выражение.

Обратите внимание, что мы можем объединиться и с литеральной записью:

 z = {**x, 'foo': 1, 'bar': 2, **y}
 

и теперь:

 >>> г
{'a': 1, 'b': 3, 'foo': 1, 'bar': 2, 'c': 4}
 

Теперь он отображается как реализованный в расписании выпуска для 3.5, PEP 478, и теперь он попал в документ Что нового в Python 3.5.

Однако, поскольку многие организации все еще используют Python 2, вы можете сделать это обратно совместимым способом. Классический питонический способ, доступный в Python 2 и Python 3.0-3.4, состоит в том, чтобы сделать это как двухэтапный процесс:0015

 z = x.copy()
z.update(y) # который возвращает None, так как мутирует z
 

В обоих подходах y будет вторым, и его значения заменят значения x , таким образом, b будет указывать на 3 в нашем конечном результате.

Еще не на Python 3.

5, но вам нужно одиночное выражение

Если вы еще не используете Python 3.5 или вам нужно написать обратно совместимый код, и вы хотите, чтобы это было в одиночном выражении , наиболее производительным и правильным подходом будет поместить его в функцию:

 по определению merge_two_dicts(x, y):
    """Дано два словаря, объединить их в новый словарь как неглубокую копию."""
    г = х.копировать ()
    г.обновление(у)
    вернуть Z
 

и тогда у вас есть одно выражение:

 z = merge_two_dicts(x, y)
 

Вы также можете создать функцию для объединения произвольного количества словарей, от нуля до очень большого числа:

 def merge_dicts(*dict_args):
    """
    Учитывая любое количество словарей, мелкое копирование и объединение в новый словарь,
    приоритет отдается парам ключ-значение в последних словарях.
    """
    результат = {}
    для словаря в dict_args:
        результат.обновление(словарь)
    вернуть результат
 

Эта функция будет работать в Python 2 и 3 для всех словарей. например заданные словари a до g :

 z = merge_dicts(a, b, c, d, e, f, g)
 

и пары ключ-значение в g будут иметь приоритет над словарями a до f и так далее.

Критика других ответов

Не используйте то, что вы видите в ранее принятом ответе:

 z = dict(x.items() + y.items())
 

В Python 2 вы создаете два списка в памяти для каждого словаря, создаете в памяти третий список с длиной, равной длине первых двух вместе взятых, а затем отбрасываете все три списка, чтобы создать словарь. В Python 3 это приведет к ошибке , потому что вы добавляете два объекта dict_items вместе, а не два списка —

 >>> c = dict(a.items() + b.items())
Traceback (последний последний вызов):
  Файл "", строка 1, в 
TypeError: неподдерживаемые типы операндов для +: 'dict_items' и 'dict_items'
 

, и вам придется явно создавать их в виде списков, например. z = dict(список(x.items()) + список(y.items())) . Это пустая трата ресурсов и вычислительной мощности.

Аналогично, объединение items() в Python 3 ( viewitems() в Python 2.7) также завершится ошибкой, если значения являются нехэшируемыми объектами (например, списками). Даже если ваши значения являются хешируемыми, 90 125, так как наборы семантически неупорядочены, поведение не определено в отношении приоритета. Так что не делайте этого:

 >>> c = dict(a.items() | b.items())
 

В этом примере показано, что происходит, когда значения нельзя хэшировать:

 >>> x = {'a': []}
>>> у = {'b': []}
>>> dict(x.items() | y.items())
Traceback (последний последний вызов):
  Файл "", строка 1, в 
TypeError: unhashable type: 'list'
 

Вот пример, где и должны иметь приоритет, но вместо этого сохраняется значение из x из-за произвольного порядка наборов:

 >>> x = {'a': 2}
>>> у = {'а': 1}
>>> dict(x. items() | y.items())
{'а': 2}
 

Другой хак, который вы не должны использовать:

 z = dict(x, **y)
 

Здесь используется конструктор dict , он очень быстр и экономит память (даже немного больше, чем наш двухэтапный процесс), но если вы точно не знаете, что здесь происходит (то есть второй dict передается в качестве аргументов ключевого слова конструктору dict), его трудно читать, он не предназначен для использования, и, следовательно, это не Pythonic.

Вот пример исправленного использования в django.

Словари предназначены для хеширования ключей (например, FrozenSet s или кортежей), но этот метод не работает в Python 3, когда ключи не являются строками.

 >>> c = dict(a, **b)
Traceback (последний последний вызов):
  Файл "", строка 1, в 
TypeError: аргументы ключевого слова должны быть строками
 

Из списка рассылки Гвидо ван Россум, создатель языка, написал:

я в порядке объявление dict({}, **{1:3}) незаконным, так как в конце концов это злоупотребление механизм **.

и

По-видимому, dict(x, **y) используется как «крутой хак» для «вызова x.update(y) и вернуть x». Лично я нахожу это более презренным, чем прохладный.

Насколько я понимаю (а также понимание создателя языка), предполагаемое использование dict(**y) предназначено для создания словарей для удобства чтения, например:

 дикт(а=1, б=10, с=11)
 

вместо

 {'a': 1, 'b': 10, 'c': 11}
 

Ответ на комментарий

Несмотря на то, что говорит Гвидо, dict(x, **y) соответствует спецификации dict, что кстати. работает как для Python 2, так и для Python 3. Тот факт, что это работает только для строковых ключей, является прямым следствием того, как работают параметры ключевых слов, а не недостатком dict. Использование здесь оператора ** также не является злоупотреблением механизмом, фактически ** был разработан именно для передачи словарей в качестве ключевых слов.

Опять же, это не работает для 3, когда ключи не являются строками. Контракт неявного вызова заключается в том, что пространства имен принимают обычные словари, а пользователи должны передавать только аргументы ключевого слова, которые являются строками. Все остальные callables применяли это. dict нарушил эту согласованность в Python 2:

 >>> foo(**{('a', 'b'): None})
Traceback (последний последний вызов):
  Файл "", строка 1, в 
TypeError: ключевые слова foo() должны быть строками
>>> dict(**{('a', 'b'): нет})
{('а', 'б'): нет}
 

Это несоответствие было плохим, учитывая другие реализации Python (PyPy, Jython, IronPython). Таким образом, это было исправлено в Python 3, так как это использование могло быть критическим изменением.

Я заявляю вам, что преднамеренное написание кода, который работает только в одной версии языка или который работает только с определенными произвольными ограничениями, является злонамеренной некомпетентностью.

Другие комментарии:

dict(x.items() + y.items()) по-прежнему является наиболее читаемым решением для Python 2. Читабельность имеет значение.

Мой ответ: merge_two_dicts(x, y) на самом деле кажется мне намного яснее, если мы действительно заботимся о читабельности. И он не совместим с предыдущими версиями, поскольку Python 2 все больше устаревает.

{**x, **y} , похоже, не обрабатывает вложенные словари. содержимое вложенных ключей просто перезаписывается, а не объединяется […] В итоге я был сожжен этими ответами, которые не объединяются рекурсивно, и я был удивлен, что никто не упомянул об этом. В моей интерпретации слова «слияние» эти ответы описывают «обновление одного словаря другим», а не слияние.

Да. Я должен вернуть вас к вопросу, который требует мелкого слияния двух словарей, причем значения первого перезаписываются значениями второго — в одном выражении.

Предполагая наличие двух словарей словарей, можно было бы рекурсивно объединить их в одну функцию, но вы должны быть осторожны, чтобы не изменять словари из любого источника, и самый надежный способ избежать этого — сделать копию при присвоении значений. Так как ключи должны быть хэшируемыми и, как правило, неизменяемыми, копировать их бессмысленно:

 из копии импорта глубокой копии
определение dict_of_dicts_merge (х, у):
    г = {}
    перекрывающиеся_ключи = x.keys() и y.keys()
    для ключа вoverpping_keys:
        z[ключ] = dict_of_dicts_merge(x[ключ], y[ключ])
    для ключа в x.keys() - перекрывающиеся_ключи:
        z[ключ] = глубокая копия(x[ключ])
    для ключа в y.keys() - перекрывающиеся_ключи:
        z[ключ] = глубокая копия(y[ключ])
    вернуть Z
 

Использование:

 >>> x = {'a':{1:{}}, 'b': {2:{}}}
>>> у = {'b':{10:{}}, 'c': {11:{}}}
>>> dict_of_dicts_merge(x, y)
{'b': {2: {}, 10: {}}, 'a': {1: {}}, 'c': {11: {}}}
 

Придумывание непредвиденных обстоятельств для других типов значений выходит далеко за рамки этого вопроса, поэтому я укажу вам на свой ответ на канонический вопрос о «Слиянии словарей словарей».

Менее производительные, но правильные Ad-hocs

Эти подходы менее производительны, но обеспечивают правильное поведение. Они будут гораздо менее производительными, чем копия и обновление или новая распаковка, потому что они перебирают каждую пару ключ-значение на более высоком уровне абстракции, но они do соблюдать порядок старшинства (более поздние словари имеют приоритет)

Вы также можете сцепить словари вручную внутри понимания словаря:

 {k: v for d in dicts for k, v in d.items()} # iteritems в Python 2.7
 

или в Python 2.6 (и, возможно, уже в 2.4, когда были введены генераторные выражения):

 dict((k, v) for d in dicts for k, v in d.items()) # iteritems в Python 2
 

itertools.chain будет связывать итераторы по парам ключ-значение в правильном порядке:

 из цепочки импорта itertools
z = dict(chain(x.items(), y.items())) # итеритемы в Python 2
 

Анализ производительности

Я проведу анализ производительности только для тех обычаев, которые, как известно, ведут себя корректно. (Автономный, поэтому вы можете копировать и вставлять самостоятельно.)

 from timeit import repeat
из цепочки импорта itertools
х = dict.fromkeys('abcdefg')
y = dict.fromkeys('efghijk')
определение слияния_two_dicts (х, у):
    г = х.копировать ()
    г.обновление(у)
    вернуть Z
мин (повторить (лямбда: {** x, ** y}))
мин (повторить (лямбда: merge_two_dicts (x, y)))
min(repeat(lambda: {k: v для d в (x, y) для k, v в d.items()}))
мин (повторить (лямбда: dict (цепочка (x.items (), y.items ())))))
min(repeat(lambda: dict(item for d in (x, y) for item in d.items()))))
 

В Python 3.8.1, NixOS:

 >>> min(repeat(lambda: {**x, **y}))
1.0804965235292912
>>> min(repeat(лямбда: merge_two_dicts(x, y)))
1.636518670246005
>>> min(repeat(lambda: {k: v для d в (x, y) для k, v в d.items()}))
3.1779992282390594
>>> min(repeat(lambda: dict(chain(x.items(), y.items()))))
2,740647904574871
>>> min(repeat(lambda: dict(item for d in (x, y) for item in d.items())))
4.266070580109954
 
 $ uname -a
линукс никсос 4. 19.113 #1-NixOS SMP Ср, 25 марта, 07:06:15 UTC 2020 x86_64 GNU/Linux
 

Ресурсы по словарям

  • Мое объяснение реализации словаря Python , обновленное для версии 3.6.
  • Ответ о том, как добавить новые ключи в словарь
  • Отображение двух списков в словарь
  • Официальная документация Python по словарям
  • Словарь «Ещё могущественнее» — выступление Брэндона Роудса на Pycon 2017
  • Современные словари Python, слияние великих идей — выступление Рэймонда Хеттингера на Pycon 2017

словарь — Как объединить слова в Python

спросил

Изменено 5 лет, 1 месяц назад

Просмотрено 4к раз

У меня есть следующие слова:

 один: {
  'параметр': {
    а: 1
  }
}
один: {
  'параметр': {
    'б': 1
  }
}
 

И я хотел бы объединить оба, чтобы создать три :

 один: {
  'параметр': {
    а: 1,
    'Би 2
  }
}
 

Возможно ли это?

  • питон
  • словарь
6

использовать ChainMap из модуля коллекций

 из коллекций импортировать ChainMap
. ..
d1 = дикт(...)
d2 = дикт(...)
цепная карта1 = цепная карта (d1, d2)
 

Вы можете попробовать это:

 d1 = {'параметр': {'а': 1}}
d2 = {'параметр': {'b': 1}}
d1['параметр'].update(d2['параметр'])
 

Вывод:

 {'параметр': {'b': 1, 'a': 1}}
 

Или, для более общего решения:

 def get_dict(d1, d2):
   return {a: dict(c.items()+d.items()) if all(not isinstance(h, dict) for _, h in c.items()) and all(not isinstance(h, dict) for _, h in d.items()) else get_dict(c, d) for (a, c), (_, d) in zip(d1.items(), d2.items())}
 print(get_dict({'параметр': {'a': 1}}, {'параметр': {'b': 1}}))
 

Вывод:

 {'параметр': {'a': 1, 'b': 1}}
 
1

это решение создаст новый словарь, сохраняя старые:

Это в один конец. Вам нужен Python 3.5+.

 один = {'параметр': {'а': 1}}
два = {'параметр': {'b': 1}}
три = {'параметр': {**один['параметр'], **два['параметр']}}
# {'параметр': {'а': 1, 'б': 1}}
 
0

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.