Есть ли простой способ найти ключ, зная значение в словаре?
Все, о чем я могу думать, это следующее:
key = [key for key, value in dict_obj.items() if value == 'value'][0]
python
dictionary
RadiantHex
источник
источник
iteritems
поскольку для меня это дает разницу в 40 раз быстрее ... с использованием метода () .nextreverse_dictionary = {v:k for k,v in dictionary.items()}
Ответы:
Здесь ничего нет. Не забывайте, что значение может быть найдено на любом количестве ключей, включая 0 или более 1.
источник
</sigh>
Ваше понимание списка просматривает все элементы dict, находя все совпадения, а затем просто возвращает первый ключ. Это выражение генератора будет повторяться только до тех пор, пока это необходимо, чтобы вернуть первое значение:
где
dd
дикт. Будет повышаться,StopIteration
если совпадение не найдено, поэтому вы можете перехватить это и вернуть более подходящее исключение, напримерValueError
илиKeyError
.источник
keys = { key for key,value in dd.items() if value=='value' }
получить набор всех ключей, если совпадений несколько.Бывают случаи, когда словарь - это отображение один: один
Например,
Ваш подход подходит, если вы выполняете только один поиск. Однако, если вам нужно выполнить более одного поиска, будет более эффективным создать обратный словарь.
Если есть вероятность того, что несколько ключей с одинаковым значением, вам нужно будет указать желаемое поведение в этом случае.
Если ваш Python 2.6 или старше, вы можете использовать
источник
ivd=dict([(v,k) for (k,v) in d.items()])
invd = { v:k for k,v in d.items() }
Эта версия на 26% короче вашей, но работает идентично даже для избыточных / неоднозначных значений (возвращает первое совпадение, как и ваша). Однако он, вероятно, в два раза медленнее, чем ваш, потому что он создает список из dict дважды.
Или, если вы предпочитаете краткость удобочитаемости, вы можете сохранить еще один символ с помощью
А если вы предпочитаете эффективность, лучше подойдет подход @ PaulMcGuire . Если есть много ключей, которые имеют одно и то же значение, более эффективно не создавать экземпляр этого списка ключей с пониманием списка и вместо этого использовать генератор:
источник
dict.keys()
иdict.values()
соответствие гарантировано,dict
пока не изменяется между вызовами.Поскольку это все еще очень актуально, первый хит Google, и я просто потратил некоторое время на то, чтобы понять это, я опубликую свое (работающее на Python 3) решение:
Это даст вам первое совпадающее значение.
источник
Может быть,
DoubleDict
вам нужен класс, похожий на словарь, такой как ниже? Вы можете использовать любой из предоставленных метаклассов в сочетании сDoubleDict
любым метаклассом или можете вообще не использовать его.источник
Нет, вы не можете сделать это эффективно, не заглянув во все ключи и не проверив все их значения. Так что
O(n)
для этого вам понадобится время. Если вам нужно выполнить много таких поисков, вам нужно будет сделать это эффективно, построив перевернутый словарь (можно сделать также вO(n)
), а затем выполнить поиск внутри этого перевернутого словаря (каждый поиск будет выполняться в среднемO(1)
).Вот пример того, как построить перевернутый словарь (который сможет выполнять сопоставление от одного ко многим) из обычного словаря:
Например, если ваш
ваша
h_reversed
будетисточник
Насколько мне известно, его нет, но один из способов сделать это - создать диктант для обычного поиска по ключу, а другой - для обратного поиска по значению.
Вот пример такой реализации:
http://code.activestate.com/recipes/415903-two-dict-classes-which-can-lookup-keys-by-value-an/
Это означает, что поиск ключей для значения может привести к нескольким результатам, которые могут быть возвращены в виде простого списка.
источник
Я знаю, что это можно считать «расточительным», но в этом сценарии я часто сохраняю ключ как дополнительный столбец в записи значения:
это компромисс и кажется неправильным, но он прост и работает и, конечно, зависит от значений, являющихся кортежами, а не простыми значениями.
источник
Сделайте обратный словарь
Если вам нужно выполнить много обратных поисков
источник
источник
Через значения в словаре могут быть объектами любого типа, они не могут быть хешированы или проиндексированы другим способом. Так что поиск ключа по значению неестественен для этого типа коллекции. Любой подобный запрос может быть выполнен только за O (n) раз. Поэтому, если это частая задача, вам следует поискать индексацию ключа, например Jon sujjested, или, возможно, даже некоторый пространственный индекс (DB или http://pypi.python.org/pypi/Rtree/ ).
источник
Я использую словари как своего рода «базу данных», поэтому мне нужно найти ключ, который можно использовать повторно. В моем случае, если значение ключа равно
None
, я могу взять его и повторно использовать без необходимости «выделять» другой идентификатор. Просто подумал, что поделюсь этим.Мне нравится этот, потому что мне не нужно пытаться отловить какие-либо ошибки, такие как
StopIteration
илиIndexError
. Если есть доступный ключ, онfree_id
будет содержать его. Если нет, то просто будетNone
. Наверное, не питонический, но я действительно не хотел использоватьtry
здесь ...источник