Gibt es eine einfache Möglichkeit, einen Schlüssel zu finden, indem Sie den Wert in einem Wörterbuch kennen?
Ich kann mir nur Folgendes vorstellen:
key = [key for key, value in dict_obj.items() if value == 'value'][0]
python
dictionary
RadiantHex
quelle
quelle
iteritems
da dies für mich einen 40-mal schnelleren Unterschied macht ... mit der () .next-Methodereverse_dictionary = {v:k for k,v in dictionary.items()}
Antworten:
Da ist gar nichts. Vergessen Sie nicht, dass der Wert auf einer beliebigen Anzahl von Schlüsseln gefunden werden kann, einschließlich 0 oder mehr als 1.
quelle
</sigh>
Ihr Listenverständnis durchläuft alle Elemente des Diktats, um alle Übereinstimmungen zu finden, und gibt dann nur den ersten Schlüssel zurück. Dieser Generatorausdruck iteriert nur so weit wie nötig, um den ersten Wert zurückzugeben:
Wo
dd
ist das Diktat? Wird erhöht,StopIteration
wenn keine Übereinstimmung gefunden wird. Vielleicht möchten Sie diese abfangen und eine passendere Ausnahme wieValueError
oder zurückgebenKeyError
.quelle
keys = { key for key,value in dd.items() if value=='value' }
, um den Satz aller Schlüssel zu erhalten, wenn mehrere übereinstimmen.Es gibt Fälle, in denen ein Wörterbuch eine Eins-zu-Eins-Zuordnung ist
Z.B,
Ihr Ansatz ist in Ordnung, wenn Sie nur eine einzige Suche durchführen. Wenn Sie jedoch mehr als eine Suche durchführen müssen, ist es effizienter, ein inverses Wörterbuch zu erstellen
Wenn die Möglichkeit besteht, dass mehrere Schlüssel denselben Wert haben, müssen Sie in diesem Fall das gewünschte Verhalten angeben.
Wenn Ihr Python 2.6 oder älter ist, können Sie verwenden
quelle
ivd=dict([(v,k) for (k,v) in d.items()])
invd = { v:k for k,v in d.items() }
Diese Version ist 26% kürzer als Ihre , funktioniert jedoch auch bei redundanten / mehrdeutigen Werten identisch (gibt die erste Übereinstimmung zurück, wie Ihre). Es ist jedoch wahrscheinlich doppelt so langsam wie deins, da es zweimal eine Liste aus dem Diktat erstellt.
Oder wenn Sie die Kürze der Lesbarkeit vorziehen, können Sie ein weiteres Zeichen mit speichern
Und wenn Sie Effizienz bevorzugen, ist der Ansatz von @ PaulMcGuire besser. Wenn es viele Schlüssel gibt, die denselben Wert haben, ist es effizienter, diese Liste von Schlüsseln nicht mit einem Listenverständnis zu instanziieren und stattdessen einen Generator zu verwenden:
quelle
dict.keys()
unddict.values()
es wird garantiert, dass sie korrespondieren, solange dasdict
nicht zwischen Anrufen mutiert ist.Da dies immer noch sehr relevant ist, der erste Google-Treffer und ich nur einige Zeit damit verbringen, dies herauszufinden, werde ich meine (in Python 3 arbeitende) Lösung veröffentlichen:
Sie erhalten den ersten übereinstimmenden Wert.
quelle
Vielleicht ist eine wörterbuchähnliche Klasse wie
DoubleDict
unten das, was Sie wollen? Sie können jede der bereitgestellten Metaklassen in Verbindung mit einer Metaklasse verwendenDoubleDict
oder diese überhaupt vermeiden.quelle
Nein, Sie können dies nicht effizient tun, ohne alle Schlüssel einzusehen und alle ihre Werte zu überprüfen.
O(n)
Dafür brauchen Sie also Zeit. Wenn Sie viele solcher Suchvorgänge durchführen müssen, müssen Sie dies effizient tun, indem Sie ein umgekehrtes Wörterbuch erstellen (kann auch in ausgeführt werdenO(n)
) und dann eine Suche innerhalb dieses umgekehrten Wörterbuchs durchführen (jede Suche dauert durchschnittlichO(1)
).Hier ist ein Beispiel für die Erstellung eines umgekehrten Wörterbuchs (das eine bis mehrere Zuordnungen durchführen kann) aus einem normalen Wörterbuch:
Zum Beispiel, wenn Ihr
dein
h_reversed
wird seinquelle
Soweit ich weiß, gibt es keinen, aber eine Möglichkeit besteht darin, ein Diktat für die normale Suche nach Schlüssel und ein anderes Diktat für die umgekehrte Suche nach Wert zu erstellen.
Hier gibt es ein Beispiel für eine solche Implementierung:
http://code.activestate.com/recipes/415903-two-dict-classes-which-can-lookup-keys-by-value-an/
Dies bedeutet, dass das Nachschlagen der Schlüssel nach einem Wert zu mehreren Ergebnissen führen kann, die als einfache Liste zurückgegeben werden können.
quelle
Ich weiß, dass dies als "verschwenderisch" angesehen werden kann, aber in diesem Szenario speichere ich den Schlüssel häufig als zusätzliche Spalte im Wertedatensatz:
Es ist ein Kompromiss und fühlt sich falsch an, aber es ist einfach und funktioniert und hängt natürlich davon ab, dass Werte eher Tupel als einfache Werte sind.
quelle
Machen Sie ein umgekehrtes Wörterbuch
Wenn Sie viele Reverse-Lookups durchführen müssen
quelle
Durch Werte im Wörterbuch können Objekte jeglicher Art sein, die nicht auf andere Weise gehasht oder indiziert werden können. Daher ist es für diesen Sammlungstyp unnatürlich, den Schlüssel anhand des Werts zu finden. Eine solche Abfrage kann nur in O (n) -Zeit ausgeführt werden. Wenn dies also eine häufige Aufgabe ist, sollten Sie nach einer Indizierung von Schlüsseln wie Jon sujjested oder sogar nach einem räumlichen Index (DB oder http://pypi.python.org/pypi/Rtree/ ) suchen .
quelle
Ich verwende Wörterbücher als eine Art "Datenbank", daher muss ich einen Schlüssel finden, den ich wiederverwenden kann. Wenn in meinem Fall der Wert eines Schlüssels ist
None
, kann ich ihn nehmen und wiederverwenden, ohne eine andere ID "zuweisen" zu müssen. Ich dachte nur, ich würde es teilen.Ich mag dieses, weil ich nicht versuchen muss, Fehler wie
StopIteration
oder abzufangenIndexError
. Wenn ein Schlüssel verfügbar ist,free_id
enthält er einen. Wenn nicht, dann wird es einfach seinNone
. Wahrscheinlich nicht pythonisch, aber ich wolltetry
hier wirklich kein ...quelle