Ich habe also eine Liste solcher Tupel:
[(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")]
Ich möchte diese Liste für ein Tupel, dessen Zahlenwert gleich etwas ist.
Wenn ich das tue search(53)
, wird der Indexwert von zurückgegeben2
Gibt es eine einfache Möglichkeit, dies zu tun?
Sie können ein Listenverständnis verwenden :
quelle
tl; dr
Ein Generatorausdruck ist wahrscheinlich die performanteste und einfachste Lösung für Ihr Problem:
Erläuterung
Es gibt mehrere Antworten, die eine einfache Lösung für diese Frage mit Listenverständnis bieten. Diese Antworten sind zwar vollkommen richtig, aber nicht optimal. Abhängig von Ihrem Anwendungsfall können einige einfache Änderungen erhebliche Vorteile haben.
Das Hauptproblem bei der Verwendung eines Listenverständnisses für diesen Anwendungsfall besteht darin, dass die gesamte Liste verarbeitet wird, obwohl Sie nur 1 Element finden möchten .
Python bietet ein einfaches Konstrukt, das hier ideal ist. Es wird der Generatorausdruck genannt . Hier ist ein Beispiel:
Wir können erwarten, dass diese Methode im Wesentlichen die gleiche Leistung wie das Listenverständnis in unserem trivialen Beispiel erbringt. Was ist jedoch, wenn wir mit einem größeren Datensatz arbeiten? Hier kommt der Vorteil der Generatormethode ins Spiel. Anstatt eine neue Liste zu erstellen, verwenden wir Ihre vorhandene Liste als iterable und verwenden sie
next()
, um das erste Element von unserem Generator abzurufen.Schauen wir uns an, wie sich diese Methoden bei einigen größeren Datenmengen unterschiedlich verhalten. Dies sind große Listen mit 10000000 + 1 Elementen, wobei unser Ziel am Anfang (am besten) oder am Ende (am schlechtesten) liegt. Wir können anhand des folgenden Listenverständnisses überprüfen, ob beide Listen gleich gut funktionieren:
Listenverständnisse
"Schlimmsten Fall"
"I'm besten fall"
Generatorausdrücke
Hier ist meine Hypothese für Generatoren: Wir werden sehen, dass Generatoren im besten Fall eine deutlich bessere Leistung erbringen, im schlimmsten Fall jedoch ähnlich. Dieser Leistungsgewinn ist hauptsächlich auf die Tatsache zurückzuführen, dass der Generator träge ausgewertet wird, was bedeutet, dass nur berechnet wird, was erforderlich ist, um einen Wert zu erhalten.
Schlimmsten Fall
I'm besten fall
WAS?! Der beste Fall bläst weg das Listenverständnis zum Erliegen, aber ich hatte nicht erwartet, dass unser schlechtester Fall das Listenverständnis in einem solchen Ausmaß übertrifft. Wie ist das? Ehrlich gesagt konnte ich nur ohne weitere Forschung spekulieren.
Nehmen Sie all dies mit einem Körnchen Salz, ich habe hier keine robuste Profilierung durchgeführt, nur einige sehr grundlegende Tests. Dies sollte ausreichen, um zu erkennen, dass ein Generatorausdruck für diese Art der Listensuche leistungsfähiger ist.
Beachten Sie, dass dies alles grundlegende, integrierte Python ist. Wir müssen nichts importieren oder Bibliotheken verwenden.
Ich habe diese Technik zum ersten Mal für die Suche im Udacity cs212- Kurs mit Peter Norvig gesehen.
quelle
Ihre Tupel sind im Grunde Schlüssel-Wert-Paare - eine Python -
dict
also:Bearbeiten - aha, Sie sagen, Sie möchten den Indexwert von (53, "xuxa"). Wenn dies wirklich das ist, was Sie wollen, müssen Sie die ursprüngliche Liste durchlaufen oder vielleicht ein komplizierteres Wörterbuch erstellen:
quelle
l = [(1,"juca"),(22,"james"),(53,"xuxa"),(44,"delicia")] val = dict(l).get(53)
Hmm ... nun, der einfache Weg, der mir in den Sinn kommt, besteht darin, ihn in ein Diktat umzuwandeln
und Zugang
d[53]
.EDIT : Ups, falsch verstanden Ihre Frage das erste Mal. Es hört sich so an, als ob Sie tatsächlich den Index erhalten möchten, in dem eine bestimmte Nummer gespeichert ist. Versuchen Sie es in diesem Fall
anstelle einer einfachen alten
dict
Bekehrung. Dannd[53]
wäre 2.quelle
Angenommen, die Liste ist lang und die Zahlen wiederholen sich. Verwenden Sie möglicherweise den Typ SortedList aus dem Python-Sortiercontainer-Modul . Der Typ SortedList verwaltet die Tupel automatisch in der Reihenfolge ihrer Nummer und ermöglicht eine schnelle Suche.
Beispielsweise:
Dies funktioniert durch eine binäre Suche viel schneller als der Vorschlag zum Listenverständnis. Der Wörterbuchvorschlag ist noch schneller, funktioniert aber nicht, wenn doppelte Zahlen mit unterschiedlichen Zeichenfolgen vorhanden sein könnten.
Wenn es doppelte Zahlen mit unterschiedlichen Zeichenfolgen gibt, müssen Sie einen weiteren Schritt ausführen:
Durch Halbieren für 54 finden wir den Endindex für unser Slice. Dies ist auf langen Listen im Vergleich zur akzeptierten Antwort erheblich schneller.
quelle
Nur ein anderer Weg.
quelle
[k für k, v in l wenn v == ' delicia ']
hier ist l die Liste der Tupel - [(1, "juca"), (22, "james"), (53, "xuxa"), (44, "delicia")]
Und anstatt es in ein Diktat umzuwandeln, verwenden wir das Listenverständnis.
*Key* in Key,Value in list, where value = **delicia**
quelle