Приведенный словарь выглядит так:
my_map = {'a': 1, 'b': 2}
Как можно инвертировать эту карту, чтобы получить:
inv_map = {1: 'a', 2: 'b'}
python
dictionary
mapping
reverse
Брайан М. Хант
источник
источник
my_map.items()
работаетThe order-preserving aspect of this new implementation is considered an implementation detail and should not be relied upon
, Нет гарантии, что так будет и дальше, поэтому не пишите код, основанный наDict
том же поведении, что иOrderedDict
.Предполагая, что значения в dict являются уникальными:
источник
iteritems()
будет выводиться, поэтому можно предположить, что для неуникального значения будет назначен произвольный ключ способом, который, по-видимому, будет воспроизводим при некоторых условиях, но в общем случае нет.iteritems()
метода, и этот подход не будет работать; используйтеitems()
вместо этого, как показано в принятом ответе. Кроме того, понимание словаря сделало бы это красивее, чем вызовdict
.Если значения в
my_map
не уникальны:источник
inv_map.get(v, [])
возвращает уже добавленный список, если он есть, поэтому назначение не сбрасывается в пустой список.setdefault
все равно будет красивее.inv_map.setdefault(v, set()).add(k)
,my_map.items()
вместоmy_map.iteritems()
.Чтобы сделать это при сохранении типа вашего отображения (при условии, что это -
dict
илиdict
подкласс):источник
Попробуй это:
(Обратите внимание, что документы Python по представлениям словаря явно гарантируют это
.keys()
и.values()
имеют свои элементы в том же порядке, что позволяет работать описанному выше подходу.)В качестве альтернативы:
или используя pyt 3.0
источник
Другой, более функциональный способ:
источник
filter
иmap
должен умереть и быть включенным в составление списка, а не увеличивать количество вариантов».dict
с другими типами отображения, такими какcollections.OrderedDict
илиcollections.defaultdict
Это расширяет ответ Роберта , применяемый к случаям, когда значения в dict не являются уникальными.
Реализация ограничена тем, что вы не можете использовать
reversed
дважды и вернуть оригинал. Это не симметрично как таковое. Протестировано с Python 2.6. Вот пример использования того, как я использую, чтобы напечатать результирующий dict.Если вы хотели бы использовать ,
set
чемlist
, и может существовать неупорядоченные приложения , для которых это имеет смысл, вместо тогоsetdefault(v, []).append(k)
, использованиеsetdefault(v, set()).add(k)
.источник
revdict.setdefault(v, set()).add(k)
set
. Это внутренний тип, который применяется здесь. Что делать, если я хочу найти все ключи, значения которых отсутствуют1
или2
? Тогда я могу просто сделатьd.keys() - inv_d[1] - inv_d[2]
(в Python 3)Мы также можем перевернуть словарь с дубликатами ключей, используя
defaultdict
:Смотрите здесь :
источник
Например, у вас есть следующий словарь:
И вы хотите получить это в такой перевернутой форме:
Первое решение . Для инвертирования пар ключ-значение в вашем словаре используйте
for
подход -loop:Второе решение . Используйте словарный подход для инверсии:
Третье решение . Используйте обратный инверсионный подход (опирается на второе решение):
источник
dict
зарезервировано и не должно использоваться для имен переменныхmy_map
такоеdictio()
? Вы имели в видуdict()
?Сочетание списка и словаря. Может обрабатывать дубликаты ключей
источник
Если значения не уникальны, и вы немного хардкор:
Обратите внимание, что, особенно при большом требовании, это решение гораздо менее эффективно, чем ответ Python на обратное / обратное отображение, поскольку оно повторяется
items()
несколько раз.источник
-1
потому что это все еще отвечает на вопрос, только мое мнение.В дополнение к другим функциям, предложенным выше, если вам нравятся лямбды:
Или вы можете сделать это тоже так:
источник
Я думаю, что лучший способ сделать это - определить класс. Вот реализация «симметричного словаря»:
Методы удаления и итерации достаточно просты для реализации, если они необходимы.
Эта реализация более эффективна, чем инвертирование всего словаря (который, похоже, является самым популярным решением на этой странице). Не говоря уже о том, что вы можете добавлять или удалять значения из вашего SymDict столько раз, сколько захотите, и ваш обратный словарь всегда останется действительным - это не так, если вы просто полностью измените весь словарь один раз.
источник
dictresize
, но этот подход лишает Python такой возможности.Это обрабатывает неуникальные значения и сохраняет большую часть внешнего вида уникального случая.
Для Python 3.x замените
itervalues
наvalues
.источник
Функция симметрична для значений списка типов; Кортежи включаются в списки при выполнении reverse_dict (reverse_dict (словарь))
источник
Поскольку словарям требуется один уникальный ключ в словаре, в отличие от значений, мы должны добавить обратные значения в список сортировки, который будет включен в новые конкретные ключи.
источник
Быстрое функциональное решение для небиективных карт (значения не уникальны):
Теоретически это должно быть быстрее, чем добавление к набору (или добавление к списку) один за другим, как в императивном решении .
К сожалению, значения должны быть сортируемыми, сортировка требуется по группам.
источник
n
элементы в исходном дикте, ваш подход имеетO(n log n)
временную сложность из-за необходимости сортировки элементов диктанта, тогда как наивный императивный подход имеетO(n)
временную сложность. Насколько я знаю, ваш подход может быть быстрее вплоть до абсурдно большихdict
на практике , но в теории он, конечно, не быстрее.Попробуйте это для Python 2.7 / 3.x
источник
Я бы сделал это таким образом в Python 2.
источник
dict.items
(илиiteritems
в Python 2) более эффективна, чем извлечение каждого значения отдельно при итерации ключей.Это обеспечит вывод в виде: {1: ['a', 'd'], 2: ['b'], 3: ['c']}
источник
dict.items
(илиiteritems
в Python 2) более эффективна, чем извлечение каждого значения отдельно при итерации ключей. Кроме того, вы не добавили объяснения в ответ, который дублирует других.этот код сделать так:
источник
Не что-то совершенно другое, просто немного переписанный рецепт из поваренной книги. Более того, он оптимизируется путем сохранения
setdefault
метода, вместо того, чтобы каждый раз проходить его через экземпляр:Предназначен для запуска под CPython 3.x, для 2.x заменить
mapping.items()
наmapping.iteritems()
На моей машине работает чуть быстрее, чем на других примерах здесь
источник
dict
и последующее преобразование в требуемый класс в конце (вместо того, чтобы начинать с класса правильного типа) выглядит для меня так, как будто это приводит к совершенно предотвращаемому падению производительности.Я написал это с помощью цикла «for» и метода «.get ()» и изменил название «map» в словаре на «map1», потому что «map» - это функция.
источник
Если значения не уникальны, И может быть хешем (одно измерение):
И с рекурсией, если вам нужно копать глубже, чем одно измерение:
источник
{"foo": "bar"}
в{'b': ['foo'], 'a': ['foo'], 'r': ['foo']}
и вызывает исключение , если какое - либо значение вmyDict
не итератор. Я не уверен, какое поведение вы пытались реализовать здесь, но то, что вы на самом деле реализовали, это то, чего никто не хочет.