Намиране на индекса на елемент, зададен в списък, който го съдържа, в Python

Как мога да получа индекса (1) на Python за списък ["foo", "bar", "baz"] и елемент от списъка "bar"?

Решение
>>> ["foo", "bar", "baz"].index("bar")
1

Справка: Data Structures > More on Lists

Caveats follow

Обърнете внимание, че макар това да е може би най-чистият начин да отговорите на въпроса както е зададен, index е доста слаб компонент на приложния програмен интерфейс list и не мога да си спомня кога за последен път съм го използвал в гнева си. В коментарите ми беше обърнато внимание, че тъй като този отговор е силно препратен, той трябва да бъде по-пълен. Следват някои предупреждения относно list.index. Вероятно си заслужава първоначално да погледнете документацията за него:

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

Линейна времева сложност при дължина на списъка

Извикването на index проверява последователно всеки елемент от списъка, докато не намери съответствие. Ако списъкът ви е дълъг и не знаете приблизително къде в списъка се намира, това търсене може да се превърне в затруднение. В такъв случай трябва да помислите за друга структура на данните. Обърнете внимание, че ако знаете приблизително къде да намерите съвпадението, можете да дадете на index подсказка. Например в този фрагмент l.index(999_999, 999_990, 1_000_000) е приблизително пет порядъка по-бърз от директния l.index(999_999), тъй като първият трябва да търси само 10 записа, докато вторият търси милион:

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

Връща само индекса на първото съвпадение на аргумента си

Извикването на index претърсва списъка по ред, докато намери съвпадение, и спира дотук. Ако очаквате да ви трябват индекси на повече съвпадения, трябва да използвате разбиране на списък или генераторен израз.

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

На повечето места, където някога съм използвал index, сега използвам разбиране на списък или генераторен израз, защото те са по-общи. Така че, ако смятате да посегнете към index, разгледайте тези отлични възможности на Python.

Хвърля, ако елементът не присъства в списъка

Извикването на index води до ValueError, ако елементът'не присъства.

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

Ако елементът може да не присъства в списъка, трябва или

  1. първо да проверите за него с item in my_list (чист, четлив подход), или
  2. Да обвиете извикването на index в блок try/except, който улавя ValueError (вероятно по-бързо, поне когато списъкът за търсене е дълъг и елементът обикновено присъства).
Коментари (2)

Едно от нещата, които са наистина полезни при изучаването на Python, е да използвате функцията за интерактивна помощ:

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

class list(object)
 ...

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

която често ще ви отведе до търсения метод.

Коментари (1)

index() връща първия индекс на стойността!

| index(...) | L.index(value, [start, [stop]]) -> цяло число -- връща първия индекс на стойността

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"])
Коментари (3)