Пересечение и различие двух словарей

#python #dictionary

#python #словарь

Вопрос:

Учитывая два словаря, я хочу посмотреть на их взаимосвязь и различие и выполнить функцию f для элементов, которые пересекаются, и выполнить g для уникальных элементов, вот как я узнал, что такое уникальные и пересекающиеся элементы, где d1 и d2 — два словаря, как мне распечатать d_intersection и d_differenceкак словари внутри кортежа? Вывод должен выглядеть примерно так ({пересекающиеся ключи, значения}, {разные ключи, значения}), например: учитывая

 d1 = {1:30, 2:20, 3:30, 5:80}

d2 = {1:40, 2:50, 3:60, 4:70, 6:90}
  

Вывод должен быть ({1: 70, 2: 70, 3: 90}, {4: 70, 5: 80, 6: 90})

 dic = {}
d_intersect = set(d1) amp; set(d2)
d_difference =  set(d1) ^ set(d2)
for i in d_intersect:
    dic.update({i : f(d1[i],d2[i])})
for j in d_difference:
    dic.update({j : g(d1[j],d2[j])})
  

Может кто-нибудь сказать мне, где я ошибался и почему мой код выдает ошибку ключа 4?

Комментарии:

1. Предложение: ваш вопрос запутанный, его нелегко понять, а код выглядит странно. Что это за язык программирования? Когда вы говорите, что ожидаете определенного вывода, но не предоставляете входные данные, практически невозможно понять, что вы ищете.

2. Извините, отредактировал это сейчас. Это python и один из вопросов для викторины, и я пытался его решить. Я довольно новичок в python, поэтому мой код выглядит очень некрасиво

3. На выходе похоже, что вам нужен кортеж из двух словарей. Функция dict_interdif выдает один словарь.

Ответ №1:

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

 d1 = {1: 30, 2: 20, 3: 30, 5: 80}

d2 = {1: 40, 2: 50, 3: 60, 4: 70, 6: 90}

 # d1.keys() ^ d2 -> {4, 5, 6}, 4, 6 unique to d2, 5 unique to d1.
symm = {k: d1.get(k, d2.get(k)) for k in d1.keys() ^ d2}
inter = {k: d2[k]   d1[k] for k in d1.keys() amp; d2}
  

d1.get(k, d2.get(k)) работает для симметричной разницы, поскольку она улавливается, когда мы получаем уникальный ключ от d2 .

Код для python2 немного отличается, вам нужно будет заменить .keys на .viewkeys , чтобы получить объект просмотра:

  {k: d1.get(k, d2.get(k)) for k in d1.viewkeys() ^ d2}
 {k: d2[k]   d1[k]  for k in d1.viewkeys() amp; d2}
  

Чтобы получить только разницу между двумя наборами, то есть то, что находится в a, но не в b, вам нужно - :

 In [1]: d1 = {1: 30, 2: 20, 3: 30, 5: 80}

In [2]: d2 = {1: 40, 2: 50, 3: 60, 4: 70, 6: 90}

In [3]: {k: d2[k] for k in d2.keys() - d1}
Out[3]: {4: 70, 6: 90}

In [4]: {k: d1[k] for k in d1.keys() - d2}
Out[4]: {5: 80}
In [5]: d2.keys() - d1 # in d2 not in d1
Out[5]: {4, 6}

In [6]: d1.keys() - d2 # in d1 not in d2
Out[6]: {5}

In [7]: d1.keys() ^ d2 # unique to either
Out[7]: {4, 5, 6}
  

Симметричное различие похоже на объединение различий:

 In [12]: d1.keys() - d2 |  d2.keys() - d1
Out[12]: {4, 5, 6}
  

Все операторы обсуждаются в документах python, также страница wiki на Set_ (математика) дает вам хороший обзор.

Комментарии:

1. таким образом, симметричная разница улавливает значение только тогда, когда его нет в обоих словарях, а только в одном? Я хотел, чтобы любой элемент из обоих словарей отсутствовал в другом. Например, {5:80} не присутствовал в d2, и я хотел, чтобы аналогично я хотел {4: 70, 6: 90}, поскольку они не присутствовали в d1. Любые хорошие источники, которые я могу изучить по этим наборам и пересечению множеств? Спасибо за ответ, кстати

2. @user6820366, симметричная разница двух наборов будет содержать элементы из любого набора, которые являются уникальными для этого набора. Я добавил еще несколько примеров.

3. Я вижу, что это имеет смысл, симметричное различие — это объединение различий ключей в каждом словаре. Спасибо, это было очень информативно: D

4. @user6820366, точно в a, а не в b и наоборот. Просто подумайте о симметричной разнице как уникальной для каждого набора.

Ответ №2:

Вот один из способов сделать это, хотя может быть и более эффективный метод.

 d1 = {1:30, 2:20, 3:30, 5:80}
d2 = {1:40, 2:50, 3:60, 4:70, 6:90}

d_intersect = {} # Keys that appear in both dictionaries.
d_difference = {} # Unique keys that appear in only one dictionary.

# Get all keys from both dictionaries.
# Convert it into a set so that we don't loop through duplicate keys.
all_keys = set(d1.keys()   d2.keys()) # Python2.7
#all_keys = set(list(d1.keys())   list(d2.keys())) # Python3.3

for key in all_keys:
    if key in d1 and key in d2:
        # If the key appears in both dictionaries, add both values
        # together and place it in intersect.
        d_intersect[key] = d1[key]   d2[key]
    else:
        # Otherwise find out the dictionary it comes from and place
        # it in difference.
        if key in d1:
            d_difference[key] = d1[key]
        else:
            d_difference[key] = d2[key]
  

Вывод:

{1: 70, 2: 70, 3: 90}

{4: 70, 5: 80, 6: 90}

Комментарии:

1. Не могли бы вы также объяснить, как работает код, я знаю, что это слишком много, чтобы спрашивать, но мне бы очень хотелось знать, как работает этот код, чтобы я мог создать свой собственный код на основе вашего. Спасибо.

2. Конечно, я включу комментарии.

3. Большое вам спасибо! строка all_keys = set(d1.keys() d2.keys()) выдает ошибку TypeError: неподдерживаемый тип (ы) операнда для : ‘dict_keys’ и ‘dict_keys’

4. Каковы ваши значения для d1 и d2?

5. Те же значения, которые я ввел в вопрос, они вообще не были изменены, я попытался запустить этот код на pythontutor, и он выдал мне эту ошибку.