Czy istnieje prosty sposób na znalezienie klucza poprzez znajomość wartości w słowniku?
Myślę tylko o tym:
key = [key for key, value in dict_obj.items() if value == 'value'][0]
python
dictionary
RadiantHex
źródło
źródło
iteritems
jak dla mnie, to robi 40x szybszą różnicę ... używając metody () .nextreverse_dictionary = {v:k for k,v in dictionary.items()}
Odpowiedzi:
Nie ma żadnego. Nie zapominaj, że wartość można znaleźć na dowolnej liczbie kluczy, w tym 0 lub więcej niż 1.
źródło
</sigh>
Twoja lista składa się z wszystkich elementów dykta, znajdując wszystkie dopasowania, a następnie zwraca pierwszy klucz. To wyrażenie generatora będzie iterować tylko tak daleko, jak to konieczne, aby zwrócić pierwszą wartość:
gdzie
dd
jest dyktando. Podniesie,StopIteration
jeśli nie zostanie znalezione dopasowanie, więc możesz chcieć to złapać i zwrócić bardziej odpowiedni wyjątek, taki jakValueError
lubKeyError
.źródło
keys = { key for key,value in dd.items() if value=='value' }
aby uzyskać zestaw wszystkich kluczy, jeśli kilka pasuje.Są przypadki, w których słownik jest jeden: jedno mapowanie
Na przykład,
Twoje podejście jest w porządku, jeśli wykonujesz tylko jedno wyszukiwanie. Jeśli jednak potrzebujesz wykonać więcej niż jedno wyszukiwanie, skuteczniejsze będzie utworzenie słownika odwrotnego
Jeśli istnieje możliwość, że wiele kluczy ma tę samą wartość, w tym przypadku należy określić żądane zachowanie.
Jeśli Twój Python jest w wersji 2.6 lub starszej, możesz użyć
źródło
ivd=dict([(v,k) for (k,v) in d.items()])
invd = { v:k for k,v in d.items() }
Ta wersja jest o 26% krótsza od twojej, ale działa identycznie, nawet dla zbędnych / niejednoznacznych wartości (zwraca pierwsze dopasowanie, tak jak twoja). Jest jednak prawdopodobnie dwa razy wolniejszy niż twój, ponieważ dwukrotnie tworzy listę na podstawie dyktowania.
Lub jeśli wolisz zwięzłość niż czytelność, możesz zapisać jeszcze jedną postać
A jeśli wolisz wydajność, podejście @ PaulMcGuire jest lepsze. Jeśli istnieje wiele kluczy, które mają tę samą wartość, bardziej efektywne jest nie tworzenie instancji tej listy kluczy ze zrozumieniem listy i zamiast tego użyć generatora:
źródło
dict.keys()
idict.values()
gwarantujemy, że będą korespondować, o iledict
nie będą mutowane między połączeniami.Ponieważ jest to nadal bardzo istotne, pierwsze trafienie Google i spędziłem trochę czasu na zastanowieniu się nad tym, opublikuję moje rozwiązanie (działające w Pythonie 3):
Otrzymasz pierwszą pasującą wartość.
źródło
Może chcesz uzyskać klasę podobną do słownika, taką jak
DoubleDict
poniżej? Możesz użyć dowolnej z dostarczonych metaklas w połączeniu zDoubleDict
dowolną metaklasą lub możesz w ogóle jej uniknąć.źródło
Nie, nie można tego skutecznie zrobić bez zaglądania do wszystkich kluczy i sprawdzania wszystkich ich wartości. Będziesz więc potrzebował
O(n)
czasu, aby to zrobić. Jeśli potrzebujesz wykonać wiele takich wyszukiwań, będziesz musiał to zrobić efektywnie, konstruując odwrócony słownik (można to również zrobić wO(n)
), a następnie przeszukując ten odwrócony słownik (każde wyszukiwanie zajmie średnioO(1)
).Oto przykład, jak skonstruować odwrócony słownik (który będzie w stanie wykonać jedno do wielu mapowań) ze zwykłego słownika:
Na przykład, jeśli twój
twoja
h_reversed
wolaźródło
O ile mi wiadomo, nie ma takiego, jednak jednym ze sposobów jest utworzenie dyktu do normalnego wyszukiwania według klucza, a drugim do wyszukiwania wstecznego według wartości.
Oto przykład takiej implementacji:
http://code.activestate.com/recipes/415903-two-dict-classes-which-can-lookup-keys-by-value-an/
Oznacza to, że wyszukiwanie kluczy pod kątem wartości może skutkować wieloma wynikami, które można zwrócić jako prostą listę.
źródło
Wiem, że można to uznać za `` marnotrawstwo '', ale w tym scenariuszu często przechowuję klucz jako dodatkową kolumnę w rekordzie wartości:
jest to kompromis i wydaje się zły, ale jest prosty i działa i oczywiście zależy od wartości będących krotkami, a nie prostymi wartościami.
źródło
Stwórz słownik zwrotny
Jeśli masz dużo do zrobienia odwrotnego wyszukiwania
źródło
Wartości w słowniku mogą być obiektami dowolnego rodzaju, których nie można haszować ani indeksować w inny sposób. Zatem znajdowanie klucza według wartości jest nienaturalne dla tego typu kolekcji. Każde takie zapytanie może zostać wykonane tylko w czasie O (n). Więc jeśli jest to częste zadanie, powinieneś spojrzeć na indeksowanie klucza, takiego jak Jon Sujjested, a może nawet indeks przestrzenny (DB lub http://pypi.python.org/pypi/Rtree/ ).
źródło
Używam słowników jako pewnego rodzaju „bazy danych”, więc muszę znaleźć klucz, którego będę mógł ponownie użyć. W moim przypadku, jeśli wartość klucza to
None
, mogę go wziąć i ponownie użyć bez konieczności „przydzielania” innego identyfikatora. Pomyślałem, że się tym podzielę.Podoba mi się ten, ponieważ nie muszę próbować wyłapywać żadnych błędów, takich jak
StopIteration
lubIndexError
. Jeśli jest dostępny klucz,free_id
będzie go zawierał. Jeśli nie, to po prostu będzieNone
. Prawdopodobnie nie pythoniczne, ale naprawdę nie chciałemtry
tutaj używać ...źródło