Ich habe eine Liste von Diktaten:
list = [{'id':'1234','name':'Jason'},
{'id':'2345','name':'Tom'},
{'id':'3456','name':'Art'}]
Wie kann ich die Indexposition [0], [1] oder [2] effizient finden, indem ich auf name = 'Tom' übereinstimme?
Wenn dies eine eindimensionale Liste wäre, könnte ich list.index () ausführen, bin mir aber nicht sicher, wie ich vorgehen soll, indem ich die Werte der Diktate in der Liste suche.
{ 'Jason': {'id': '1234'}, 'Tom': {'id': '1245'}, ...}
?){'1234': {'name': 'Jason'}, ...}
. Nicht, dass das diesem Anwendungsfall helfen würde.Antworten:
Wenn Sie wiederholt vom Namen abrufen müssen, sollten Sie sie nach Namen indizieren (mithilfe eines Wörterbuchs). Auf diese Weise erhalten Abrufvorgänge die Zeit O (1). Eine Idee:
quelle
next()
dies für mich seltsam erscheint), ist das Ziel nur, den Index zu erhalten. Dies löst auch StopIteration aus, während die Python-lst.index()
Methode ValueError auslöst.first()
klingt besser. Sie können jederzeit versuchen / mit Ausnahme der StopIteration und ValueError auslösen, damit der Aufrufer konsistent ist. Alternativ können Sie dennext()
Standardwert auf -1 setzen.SyntaxError: Generator expression must be parenthesized if not sole argument
dabei.next((index for (index, d) in enumerate(lst) if d["name"] == "Tom"), None)
Eine einfach lesbare Version ist
quelle
str.find()
gut nach. Sie können es auch aufrufenindex()
und ein erhöhen,ValueError
anstatt -1 zurückzugeben, wenn dies vorzuziehen ist.Dies ist nicht effizient, da Sie die Liste durchgehen müssen, um alle darin enthaltenen Elemente zu überprüfen (O (n)). Wenn Sie Effizienz wünschen, können Sie Diktate verwenden . Bei der Frage gibt es eine Möglichkeit, sie zu finden (wenn Sie sich jedoch an diese Datenstruktur halten möchten, ist es tatsächlich effizienter, einen Generator zu verwenden, wie Brent Newey in den Kommentaren geschrieben hat; siehe auch die Antwort von tokland):
quelle
Hier ist eine Funktion, die die Indexposition des Wörterbuchs ermittelt, falls vorhanden.
quelle
Scheint am logischsten, eine Filter / Index-Kombination zu verwenden:
Und wenn Sie denken, dass es mehrere Übereinstimmungen geben könnte:
quelle
Die von @faham angebotene Antwort ist ein netter Einzeiler, gibt jedoch den Index nicht an das Wörterbuch zurück, das den Wert enthält. Stattdessen wird das Wörterbuch selbst zurückgegeben. Hier ist ein einfacher Weg, um zu erhalten: Eine Liste von Indizes, eine oder mehrere, wenn es mehr als eine gibt, oder eine leere Liste, wenn es keine gibt:
Ausgabe:
Was mir an diesem Ansatz gefällt, ist, dass Sie mit einer einfachen Bearbeitung eine Liste sowohl der Indizes als auch der Wörterbücher als Tupel erhalten können. Dies ist das Problem, das ich lösen und diese Antworten finden musste. Im Folgenden habe ich einen doppelten Wert in ein anderes Wörterbuch eingefügt, um zu zeigen, wie es funktioniert:
Ausgabe:
Diese Lösung findet alle Wörterbücher, die 'Tom' in einem ihrer Werte enthalten.
quelle
Einzeiler!?
quelle
Gibt für eine gegebene Iterable
more_itertools.locate
Positionen von Elementen aus, die ein Prädikat erfüllen.more_itertools
ist eine Bibliothek von Drittanbietern, die unter anderem itertools-Rezepte implementiert .quelle
quelle