>>> ["foo", "bar", "baz"].index("bar")
1
Siehe die Dokumentation für die integrierte Methode .index()
der Liste:
list.index(x[, start[, end]])
Gibt den index in der Liste des ersten Elements zurück, dessen Wert gleich x ist. Wirft einen ValueError
falls kein solches Element vorhanden ist.
Die optionalen Argumente start und end werden wie in der Slices-Notation interpretiert und dienen dazu, die Suche auf eine bestimmte Teilfolge der Liste zu begrenzen. Der zurückgegebene Index wird relativ zum Anfang der vollständigen Sequenz berechnet und nicht relativ zum Startargument.
Vorsichtsmaßnahmen
Lineare Zeitkomplexität in der Listenlänge
Ein index
-Aufruf überprüft jedes Element der Liste der Reihe nach, bis es eine Übereinstimmung findet. Wenn die Liste lang ist und keine Garantie besteht, dass der Wert nahe am Anfang liegt, kann dies den Code verlangsamen.
Dieses Problem kann nur vollständig vermieden werden, indem eine andere Datenstruktur verwendet wird. Wenn jedoch bekannt ist, dass das Element in einem bestimmten Teil der Liste enthalten ist, können die Parameter start
und end
verwendet werden, um die Suche einzuschränken.
Zum Beispiel:
>>> import timeit
>>> timeit.timeit('l.index(999_999)', setup='l = list(range(0, 1_000_000))', number=1000)
9.356267921015387
>>> timeit.timeit('l.index(999_999, 999_990, 1_000_000)', setup='l = list(range(0, 1_000_000))', number=1000)
0.0004404920036904514
Der zweite Aufruf ist um Größenordnungen schneller, da er nur durch 10 Elemente suchen muss und nicht durch alle 1 Million.
Nur der Index der ersten Übereinstimmung wird zurückgegeben
Ein Aufruf von index
durchsucht die Liste der Reihe nach, bis es eine Übereinstimmung findet, und stoppt dort. Wenn es mehr als eine Wiederholung des Werts geben könnte und alle Indizes benötigt werden, kann index
das Problem nicht lösen:
>>> [1, 1].index(1) # der Index `1` wird nicht gefunden.
0
Verwenden Sie stattdessen eine List Comprehension oder Generator-Ausdruck zur Suche, mit enumerate
zur Ermittlung der Indizes:
>>> # Eine List Comprehension gibt direkt eine Liste von Indizes zurück:
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> # Ein Generator-Ausdruck gibt uns ein iterierbares Objekt...
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> # das in einer `for`-Schleife verwendet werden kann oder manuell mit `next` durchlaufen werden kann:
>>> next(g)
0
>>> next(g)
2
Die Techniken der List Comprehension und des Generatorausdrucks funktionieren auch bei nur einer Übereinstimmung und sind allgemeiner anwendbar.
Wirft eine Ausnahme, wenn keine Übereinstimmung vorhanden ist
Wie oben in der Dokumentation erwähnt, wirft die Verwendung von .index
eine Ausnahme, wenn der gesuchte Wert nicht in der Liste vorhanden ist:
>>> [1, 1].index(2)
Traceback (most recent call last):
File "", line 1, in
ValueError: 2 is not in list
Wenn dies ein Problem ist, überprüfen Sie zuerst explizit mit Verwendung von Element in myList
, oder behandeln Sie die Ausnahme mit try
/except
entsprechend.
Die explizite Überprüfung ist einfach und lesbar, erfordert jedoch eine erneute Iteration der Liste. Siehe Was ist das EAFP-Prinzip in Python? für weitere Anleitungen zu dieser Entscheidung.
16 Stimmen
Übersetzung: Kehren Sie zurück: [1] Der niedrigste Index im Falle mehrerer Instanzen von
"bar"
, [2] Alle Indizes von"bar"
?7 Stimmen
A) Ist es garantiert, dass der Eintrag in der Liste ist, oder wie sollten wir den Fehlerfall behandeln? (None zurückgeben/ ValueError werfen) b) Sind Listeneinträge garantiert einzigartig, und sollten wir den ersten Index eines Treffers zurückgeben oder alle Indizes?
1 Stimmen
Betrachten Sie die Antworten mit numpy-Integration, numpy-Arrays sind weitaus effizienter als Python-Listen. Wenn die Liste kurz ist, ist es kein Problem, eine Kopie davon aus einer Python-Liste zu machen. Wenn nicht, sollten Sie vielleicht erwägen, die Elemente gleich von Anfang an in einem numpy-Array zu speichern.
1 Stimmen
Ich stimme dafür, diese Frage zu schließen (aus Protest), weil es bereits 42 nicht gelöschte Antworten gibt (und 16 weitere gelöschte) für eine einfache, Einzeiler-Referenzfrage, bei der fast alle den gleichen Kernfunktion im verwenden (wie sie es sollten, weil es der einzige vernünftige und gesunde Ansatz für das Problem ist und alles darum herum nur Fehlerüberprüfung oder kreatives Neuinterpretieren der Spezifikation ist, was immer noch nur einen anderen vernünftigen, gesunden Ansatz zum erweiterten Problem hinterlässt).
0 Stimmen
Es gibt keine realistische Chance, dass in zukünftigen Versionen von Python ein besserer Ansatz möglich wird, da der vorhandene Ansatz bereits das Aufrufen einer einzigen integrierten Methode in der Liste ist - so einfach wie es nur geht.