Suche nach dem Index eines Elements in einer Liste in Python

Wie erhalte ich in Python für eine Liste ""foo", "bar", "baz"" und ein Element in der Liste ""bar"" dessen Index (1)?

Lösung
>>> ["foo", "bar", "baz"].index("bar")
1

Referenz: Datenstrukturen > Mehr über Listen

Caveats folgen

Beachten Sie, dass dies zwar vielleicht die sauberste Art ist, die Frage so wie sie gestellt wurde zu beantworten, aber index ist eine eher schwache Komponente der list API, und ich kann mich nicht erinnern, wann ich sie das letzte Mal im Zorn benutzt habe. In den Kommentaren wurde ich darauf hingewiesen, dass diese Antwort vollständiger sein sollte, da sie stark referenziert ist. Es folgen einige Vorbehalte zu list.index. Es lohnt sich wahrscheinlich, zunächst einen Blick in den Docstring dafür zu werfen:

>>> print(list.index.__doc__)
L.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.

Lineare Zeitkomplexität bei Listenlänge

Ein index-Aufruf überprüft jedes Element der Liste der Reihe nach, bis er eine Übereinstimmung findet. Wenn Ihre Liste lang ist und Sie nicht ungefähr wissen, an welcher Stelle in der Liste sie vorkommt, könnte diese Suche zu einem Engpass werden. In diesem Fall sollten Sie eine andere Datenstruktur in Betracht ziehen. Wenn Sie ungefähr wissen, wo die Übereinstimmung zu finden ist, können Sie index einen Hinweis geben. In diesem Ausschnitt ist beispielsweise l.index(999_999, 999_990, 1_000_000) etwa fünf Größenordnungen schneller als l.index(999_999), weil ersteres nur 10 Einträge durchsuchen muss, während letzteres eine Million durchsucht:

>>> 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

Gibt nur den Index der ersten Übereinstimmung mit seinem Argument zurück

Ein Aufruf von index durchsucht die Liste der Reihe nach, bis er eine Übereinstimmung findet, und hält dort an. Wenn Sie erwarten, dass Sie die Indizes weiterer Übereinstimmungen benötigen, sollten Sie ein Listenverständnis oder einen Generatorausdruck verwenden.

>>> [1, 1].index(1)
0
>>> [i for i, e in enumerate([1, 2, 1]) if e == 1]
[0, 2]
>>> g = (i for i, e in enumerate([1, 2, 1]) if e == 1)
>>> next(g)
0
>>> next(g)
2

An den meisten Stellen, an denen ich früher index verwendet hätte, verwende ich jetzt ein Listenverständnis oder einen Generatorausdruck, weil sie verallgemeinerbar sind. Wenn Sie also in Erwägung ziehen, zu index zu greifen, werfen Sie einen Blick auf diese hervorragenden Python-Funktionen.

Wirft, wenn Element nicht in Liste vorhanden

Ein Aufruf von index resultiert in einem ValueError, wenn das Element nicht vorhanden ist.

>>> [1, 1].index(2)
Traceback (most recent call last):
  File "", line 1, in 
ValueError: 2 is not in list

Wenn das Element in der Liste nicht vorhanden sein könnte, sollten Sie entweder

  1. Zuerst mit item in my_list nachsehen (sauberer, lesbarer Ansatz), oder
  2. Den index-Aufruf in einen try/except-Block verpacken, der ValueError abfängt (wahrscheinlich schneller, zumindest wenn die zu durchsuchende Liste lang ist, und der Eintrag normalerweise vorhanden ist).
Kommentare (2)

Eine Sache, die beim Erlernen von Python sehr hilfreich ist, ist die Verwendung der interaktiven Hilfefunktion:

>>> help(["foo", "bar", "baz"])
Help on list object:

class list(object)
 ...

 |
 |  index(...)
 |      L.index(value, [start, [stop]]) -> integer -- return first index of value
 |

die Sie oft zu der Methode führt, die Sie suchen.

Kommentare (1)

index() gibt den ersten Index von value zurück!

| index(...) | L.index(value, [start, [stop]]) -> integer -- gibt den ersten Index des Wertes zurück

def all_indices(value, qlist):
    indices = []
    idx = -1
    while True:
        try:
            idx = qlist.index(value, idx+1)
            indices.append(idx)
        except ValueError:
            break
    return indices

all_indices("foo", ["foo","bar","baz","foo"])
Kommentare (3)