инвертирование словаря на Python

#python #dictionary #reverse #invert

Вопрос:

Это код, который инвертирует словарь, но я столкнулся с некоторыми проблемами, чтобы понять роль каждого элемента кода в определенной функции invert_dict(dic), было бы здорово, если бы кто-нибудь разбил его на меня и объяснил мне миссию каждого элемента. Спасибо.

 animals = {'Lion':["meet", 1.2 ,'yellow'],'Cat':["milk", 0.3,'white'],'dog':["Dog", 1,'black']}

def invert_dict(dic):
    return {v: d.setdefault(v, []).append(k) or d[v] for d in ({},) for k in dic for v in dic[k]}

print(invert_dict(animals))
 

Вывод:

 {'meet': ['Lion'], 1.2: ['Lion'], 'yellow': ['Lion'], 'milk': ['Cat'], 0.3: ['Cat'], 'white': ['Cat'], 'Dog': ['dog'], 1: ['dog'], 'black': ['dog']}
 

Ответ №1:

Звучит как классическое использование для defaultdict

 animals = {'Lion':["meet", 1.2 ,'yellow'],'Cat':["milk", 0.3,'white'],'dog':["Dog", 1,'black']}

from collections import defaultdict
def invert_dict(d):
    ret = defaultdict(list)
    d = [(v,k) for k, lst in d.items() for v in lst]
    for k,v in d.items():
        ret[k].append(v)
    return dict(ret)
 

Ответ №2:

 {v: d.setdefault(v, []).append(k) or d[v] for d in ({},) for k in dic for v in dic[k]}
 

Давайте разберем это с правильной стороны

 for k in dic for v in dic[k]
 

Использует словарь со значениями в виде списков { k: [v1, v2] } и извлекает соответствующий ключ как k и список значений в v = [v1, v2]

 v: d.setdefault(v, []).append(k) or d[v] for d in ({},)
 

for v in dic[k] Циклы значений для каждого ключа, т. е. [v1, v2] и использует a defaultdict для идентификации значения, уже существующего в результирующем словаре, если это так, он добавляет ключ из исходного словаря в новый результирующий перевернутый словарь. Если нет, он назначает ключ.

Для примера { k: [v1, v2, v3], z: [v1] } после каждого запуска состояние перевернутого словаря выглядит следующим образом:

 {}
{ v1 : [k] }
{ v1 : [k], v2 : [k] }
{ v1 : [k], v2 : [k], v3: [k] }
{ v1 : [k, z], v2 : [k], v3: [k] }  # because v1 already exists, z is appended
 

Это эквивалентно:

 from collections import defaultdict

def invert_dict_exploded(dic):
    d = defaultdict(list)
    for key in dic:
        for value in dic[key]:
            d[value].append(key)
    return dict(d)
 

Ответ №3:

Нам нужно идти по порядку, снаружи внутрь:

  • Скобки и обозначение толстой кишки
  • Для петель
  • Добавить или значение

Подтяжки

Фигурные скобки используются в Python для создания словаря или набора. В этом случае они используются для создания словаря, так как у нас есть обозначение {ключ: значение}. В этом обсуждении давайте назовем его «возвращенный словарь».

Для петель

Эти циклы for эквивалентны:

 for d in ({},):
    for k in dic:
        for v in dic.values():
            ...
 

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

Он for d in ({},) используется только для объявления словаря, который будет находиться там во время перебора ключей и значений (потому что, как мы видим выше, он находится в самом внешнем цикле). Словарь имеет название d .

Добавить или значение

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

  1. Добавьте элемент в наш словарь d, который всегда представляет собой список
  2. Назначьте список данному ключу

k.setdefault(v, []) Бит установит значение по умолчанию [] , если ключ v не найден в словаре, а затем вернет этот список (вновь созданный пустой список или список, найденный в этом ключе), который затем используется .append(k) битом для добавления ключа в качестве значения в этот список. Это относится к случаям, когда у вас есть элементы в списке ввода с одинаковым значением, собирая все ключи вместе для этого значения, как в:

 animals = {'Lion':["meet", 1.2 ,'yellow'],'Cat':["milk", 0.3,'black'],'dog':["Dog", 1,'black']}
 

Где вы можете увидеть несколько списков, содержащих «черный» элемент, и выведете следующее:

 {'meet': ['Lion'], 1.2: ['Lion'], 'yellow': ['Lion'], 'milk': ['Cat'], 0.3: ['Cat'], 'black': ['Cat', 'dog'], 'Dog': ['dog'], 1: ['dog']}
 

Обратите внимание, что в результате в «черный» список добавляются ключи «Кошка» и «собака».

Наконец, часть «или«. list.append() Функция всегда возвращается None , так как каждая функция, которая не возвращается явно, автоматически возвращается None в Python.

or Оператор используется для короткого замыкания выражения. Оно записывается как A or B и должно читаться как «Если значение A равно истинному значению, выражение равно A; если значение A равно ложному значению, выражение равно B». None всегда принимает значение false в логических терминах, поэтому выражение d.setdefault(v, []).append(k) or d[v] всегда d[v] принимает значение, но только после выполнения setdefault() и append() .

v: d.setdefault(v, []).append(k) or d[v] поэтому может быть прочитано как:

Создайте ключ v в нашем возвращаемом словаре; если v это не ключ d , установите d[v] = [] ; добавьте к d[v] значению k и установите d[v] в качестве значения v .