Обратное/инвертирование отображения словаря
У меня есть словарь, например, такой:
my_map = {'a': 1, 'b': 2}
Как я могу инвертировать этот словарь так, чтобы получить:
inv_map = {1: 'a', 2: 'b'}
В чем заключается проблема, и как правильно выполнить такую операцию в Python?
5 ответ(ов)
Для перевода кода на Python 2 в эквивалентный код на Python 3+, вы можете использовать метод items()
вместо iteritems()
для получения пар ключ-значение из словаря. В Python 3+ метод items()
возвращает представление, которое ведет себя аналогично iteritems()
из Python 2. Вот как это будет выглядеть:
# Для Python 3+
inv_map = {v: k for k, v in my_map.items()}
В Python 2 использование iteritems()
было предпочтительным, так как это возвращало итератор, что было более эффективно с точки зрения использования памяти. Тем не менее, в Python 3+ вы можете использовать items()
, и это не приведет к значительному увеличению расхода памяти, так как Python 3 делает оптимизации под капотом.
Таким образом, в Python 3+ код остается таким же, но вы просто используете items()
вместо iteritems()
.
Если предположить, что значения в словаре уникальны, вы можете воспользоваться следующими способами для создания нового словаря с обменом местами ключей и значений:
Для Python 3:
dict((v, k) for k, v in my_map.items())
Для Python 2:
dict((v, k) for k, v in my_map.iteritems())
Таким образом, в обоих случаях создается новый словарь, где ключи и значения поменяны местами. Обратите внимание, что метод items()
используется в Python 3, а iteritems()
в Python 2.
Если значения в my_map
не уникальны, то можно создать инвертированную карту, где каждому значению будет соответствовать список ключей. Вот как это можно сделать на Python 3:
inv_map = {}
for k, v in my_map.items():
inv_map[v] = inv_map.get(v, []) + [k]
В этом коде мы проходим по каждому элементу словаря my_map
, извлекаем ключи и добавляем их в список по соответствующему значению в inv_map
. Если значение уже существует в inv_map
, мы просто добавляем новый ключ в уже существующий список. Если значение отсутствует, создается новый список с текущим ключом.
Для Python 2 код будет выглядеть аналогично, но с использованием метода iteritems()
:
inv_map = {}
for k, v in my_map.iteritems():
inv_map[v] = inv_map.get(v, []) + [k]
Таким образом, мы получим инвертированную карту, где значения становятся ключами, а ключи из оригинального словаря собираются в списки.
Чтобы выполнить это, сохранив тип вашего отображения (предполагая, что это dict
или подкласс dict
), вы можете использовать следующий код:
def inverse_mapping(f):
return f.__class__(map(reversed, f.items()))
Этот код создает новый объект соответствующего типа, используя map
для разворачивания пар ключ-значение из исходного отображения. Метод reversed
применяется к каждому элементу, чтобы поменять местами ключи и значения, а затем создается новый объект нужного типа с помощью f.__class__()
.
Вот еще один, более функциональный способ:
my_map = { 'a': 1, 'b': 2 }
result = dict(map(reversed, my_map.items()))
Этот код использует функцию map()
для применения функции reversed
к каждому элементу items()
исходного словаря my_map
. В результате получается итератор, который возвращает кортежи с перевернутыми парами (значение, ключ). Затем dict()
преобразует этот итератор обратно в словарь. Таким образом, вы меняете местами ключи и значения в словаре.
Как вернуть ключи словаря в виде списка в Python?
Создание словаря с помощью генератора словарей
Как скопировать словарь и редактировать только копию
Преобразование списка словарей в DataFrame pandas
Следует ли использовать 'has_key()' или 'in' для проверки наличия ключа в словарях Python?