Gewusst wie: abrufen von python dict, wo der Schlüssel ist nur zum Teil bekannt ist?
Ich habe eine dict
dass hat den Typ string-Schlüssel, deren genaue Werte kann ich nicht wissen (weil Sie dynamisch erzeugt an anderer Stelle). Allerdings weiß ich, dass das der Schlüssel, ich will mit einer bestimmten Teilstring, und dass eine einzelne Taste, die mit dieser unterzeichenfolge ist auf jeden Fall im dict.
Was ist das beste, oder "die meisten pythonic" Weg, um den Wert für diesen Schlüssel?
Dachte ich an zwei Strategien, die jedoch beide irk mir:
for k,v in some_dict.items():
if 'substring' in k:
value = v
break
-- ODER --
value = [v for (k,v) in some_dict.items() if 'substring' in k][0]
Die erste Methode ist sperrig und etwas hässlich, während der zweite Reiniger ist, aber der zusätzliche Schritt der Indizierung in der Liste das Verständnis (die [0]
) ärgert mich. Gibt es einen besseren Weg, um auszudrücken, die zweite version, oder einen kürzeren Weg zu schreiben, den ersten?
- Beide schauen ziemlich präzise als im Vergleich zu den meisten anderen Sprachen. Aber ich denke der erste ist besser lesbar.
- Warum wissen Sie über die substring? Gibt es irgendeine weitere information finden Sie? Könnten Sie tun, eine Art parsing/transformation auf die dict? Sie werden tun eine Menge der ähnliche Suchvorgänge auf der gleichen dict?
- Sie sollten versuchen
k.startswith('substring')
oderk.endswith('substring')
wenn es am Anfang oder am Ende; Sie können schneller sein. - (Karl ist ganz diskret versuchen, um Sie zu erwägen, mit einer anderen Datenstruktur, indem er über Ihre Anforderungen! Wie höflich und gut formuliert :)).
- Wenn das lookup-alle was Sie
some_dict
denn dann ist es völlig nutzlos und eine Liste wäre besser. Wenn Sie eine Liste von Teilstrings, die Sie wollen, zu entsprechen, haben Sie eine Zeit-Komplexität von O(N**2). Brauchen Sie einen index über die Tasten um dies zu tun, effizient, obwohl, Volltext-Suchmaschinen wie Sphinx zu tun, dass im Grunde. first method is bulky and somewhat ugly, while the second is cleaner
kleinen Kommentar hier: zweite ist auch nicht sauberer, es hat nur weniger\n
Zeichen. Es gibt einige seltsame überzeugung, dass single-Liner arbeiten schneller und sind besser lesbar. Sie sind es nicht.- Das dictionary (hashtable) Daten Struktur ist wirklich bedeutete für die genaue Schlüssel match: es macht nicht das partial-Schlüsselwort, passen gut zu allen, und zu versuchen, es zu biegen, zu tun, so ist gegen seine Maserung. Wie viele Einträge sind Sie auf der Suche vor?
- Ich weiß über die substring-da der code, der Sie erzeugt (@Jochen, die code-Bibliothek kann ich nicht kontrollieren) tut dies in besonderer Weise, dass die Blätter am Ende der Zeichenfolge die gleiche, aber der Anfang ist immer anders. Ich könnte diese Fahrt uns mit einem
endswith
nennen, also danke für die Idee @agf. @Jakub ich finde, die Liste Verstehens sind sehr sauber und gut lesbar, aber das ist meine subjektive Meinung. @Paolo fortunely es nur 1 jetzt, aber es könnte eine Handvoll, sobald ich mehr schreiben-handling-code. - Aber wo ist "der Teilstring" kommen? Was ist der Zweck generieren, mit dem andere strings dynamisch? @Asymptote, gut erkannt, aber "unterschiedliche Daten-Struktur" ist wohl zu spezifisch 😉
Du musst angemeldet sein, um einen Kommentar abzugeben.
Gibt es eine option zu schreiben, die zweite version mit der performance-Attribute der ersten.
Verwenden generator-Ausdruck anstelle von list comprehension:
Den Ausdruck innerhalb der Klammer gibt einen iterator, die Sie dann bitten, um die nächste, d.h. erstes element. Keine weiteren Elemente verarbeitet werden.
iteritems
auf Python 2; ansonsten ist dies meine bevorzugte Methode.items()
würde überhaupt keinen Sinn machen, eigentlich.first = next
irgendwo zu machen, es Lesen noch mehr klar... obwohl diefirst = next
Linie selbst wäre irgendwie ein WTF ich nehme an o_Ofirst
genannt wird, mehrmals auf dem gleichen iterator, z.B.it = range(10); first2 = first(v) + first(v)
Wie wäre es damit:
Wird es sofort stoppen, wenn es findet das erste match.
Aber es hat immer noch O(n) Komplexität, wobei n die Anzahl der Schlüssel-Wert-Paare. Benötigen Sie etwas, das wie ein suffix-Liste oder einem suffix-Baum die Suche beschleunigt.
next
Funktion kann auch verwendet werden, um geben Sie einen Standardwert, der zurückgegeben wird, wenn der.next()
ruft der iterator wirftStopIteration
.Wenn es gibt viele Schlüssel, aber der string ist leicht zu rekonstruieren, aus der die unterzeichenfolge, dann kann es schneller zu rekonstruieren. z.B. oft kennen Sie die start-Taste, nicht aber die Zeitstempel, die angehängt wurde, auf. (so können Sie nur versuchen, 365 Terminen statt Durchlaufen Millionen von keys für das Beispiel).
Es ist unwahrscheinlich, dass der Fall zu sein, aber ich dachte, ich würde vorschlagen es auf jeden Fall.
z.B.
Ergebnis
__init__
Funktion für MyDict ist überflüssig, da MyDict verwenden dict ist__init__
wenn es nicht eine eigene. Da deine Lösung nutzt die gleiche grundlegende Antwort wie Simon ' s, ich denke, es hat Verdienst, für jeden, der gerne eine kompliziertere Lösung, um ein problem wie dieses.Ich bevorzuge die erste version, obwohl ich es benutzen würde
some_dict.iteritems()
(wenn du auf Python 2), weil dann brauchen Sie sich nicht um die Erstellung einer kompletten Liste aller Artikel, die vorher. Stattdessen Durchlaufen die dict und brechen, sobald Sie fertig sind.Auf Python 3,
some_dict.items(2)
bereits Ergebnisse in einem Wörterbuch anzeigen, also das ist schon einen passenden iterator.