Encontrar o índice de um item dado uma lista contendo-o em Python

Para uma lista ["foo", "bar", "baz"] e um item da lista "bar", como faço para obter seu índice (1) em Python?

Solução
>>> ["foo", "bar", "baz"].index("bar")
1

Referência: Estruturas de Dados > Mais em Listas

Seguem-se as advertências

Note que embora esta seja talvez a forma mais limpa de responder à pergunta como foi feita, index é um componente bastante fraco da API list, e eu não consigo lembrar da última vez que a utilizei com raiva. Tem sido apontado para mim nos comentários que como essa resposta é fortemente referenciada, ela deveria ser mais completa. Algumas advertências sobre a list.index seguem. Provavelmente vale a pena dar uma olhada inicialmente no docstring para isso:

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

Linear time-complexity em comprimento de lista

Uma chamada index verifica cada elemento da lista em ordem, até encontrar uma correspondência. Se sua lista é longa, e você não sabe aproximadamente onde ela ocorre na lista, esta busca pode se tornar um gargalo. Nesse caso, você deve considerar uma estrutura de dados diferente. Note que se você souber aproximadamente onde encontrar a correspondência, você pode dar uma dica. Por exemplo, neste trecho, l.index(999_999, 999_990, 1_000_000) é aproximadamente cinco ordens de magnitude mais rápido que o l.index(999_999) direto, porque o primeiro só tem que pesquisar 10 entradas, enquanto o segundo pesquisa um milhão:

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

Só devolve o índice da primeira partida ao seu argumento

Uma chamada para index procura na lista em ordem até encontrar uma correspondência, e stops lá. Se você espera precisar de índices de mais correspondências, você deve utilizar uma compreensão da lista, ou expressão do gerador.

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

A maior parte dos lugares onde eu já teria utilizado index, agora uso uma compreensão de lista ou expressão de gerador porque eles são mais generalizáveis. Portanto, se você está considerando a possibilidade de utilizar `index', dê uma olhada nestas excelentes características python.

Atira se elemento não presente na lista

Uma chamada para o index resulta em um ValueError se o item não estiver presente.

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

Se o item pode não estar presente na lista, você deve

  1. Verifique primeiro com o item na minha_list (abordagem limpa e legível), ou
  2. Embrulhe a chamada index em um bloco de tenta/exceto que captura ValueError (provavelmente mais rápido, pelo menos quando a lista a ser pesquisada é longa, e o item geralmente está presente).
Comentários (2)

Uma coisa que é realmente útil na aprendizagem do Python é usar a função de ajuda interativa:

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

class list(object)
 ...

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

o que muitas vezes o levará ao método que procura.

Comentários (1)

index() retorna o primeiro índice de valor!

| index(...) | L.index(value, [start, [stop]]) -> integer -- retorna o primeiro índice de valor

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"])
Comentários (3)