Encontrar o índice de um item dado uma lista que o contém em Python

para uma lista ["foo", "bar", "baz"] e um item na lista "bar", Como é que consigo o seu Índice (1) em Python?

 2354
Author: Aaron Hall, 2008-10-07

27 answers

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

Referência: estruturas de dados > mais nas listas

Caveats follow

Note que embora esta seja talvez a maneira mais limpa de responder à pergunta Como perguntado, index é um componente fraco da API, e não me lembro da última vez que a usei com raiva. Foi-me apontado nos comentários que, como esta resposta é fortemente referenciada, deveria ser mais completa. Algumas advertências sobre list.index seguir. Provavelmente vale a pena. inicialmente a dar uma vista de olhos à Documentação:

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

Complexidade Linear de tempo na extensão da lista

Uma chamada index verifica todos os elementos da lista por ordem, até encontrar uma correspondência. Se sua lista é longa, e você não sabe mais ou menos onde na lista ela ocorre, esta pesquisa pode se tornar um gargalo. Nesse caso, você deve considerar uma estrutura de dados diferente. Note que se souber mais ou menos onde encontrar a correspondência, poderá dar uma dica a index. Por exemplo, neste trecho, l.index(999_999, 999_990, 1_000_000) é aproximadamente cinco ordens de magnitude mais rápido que a reta l.index(999_999), porque a primeira só tem que procurar 10 entradas, enquanto a segunda procura 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 correspondência ao seu argumento

Uma chamada para index procura na lista em ordem até encontrar uma correspondência, e pára aí. se você espera precisar de índices de mais correspondências, você deve usar uma compreensão de lista, ou gerador expressao.

>>> [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 maioria dos lugares onde eu já teria usado index, eu agora uso uma compreensão de lista ou expressão geradora porque eles são mais generalizáveis. Então, se você está considerando alcançar index, dê uma olhada nestas excelentes características python.

Atira se o elemento não estiver presente na lista

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

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

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

  1. verifique primeiro com item in my_list (abordagem limpa e legível), ou
  2. Enrole a chamada index num bloco try/except que captura ValueError (provavelmente mais rápido, pelo menos quando a lista a procurar é longa, e o item está normalmente presente.)
 3445
Author: Alex Coventry, 2018-06-27 04:00:35

Uma coisa que é realmente útil para aprender 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.
 795
Author: davidavr, 2008-10-07 13:19:56

A maioria das respostas explica como encontrar um único índice , mas os seus métodos não devolvem múltiplos índices se o item estiver na lista várias vezes. Utilização enumerate():

for i, j in enumerate(['foo', 'bar', 'baz']):
    if j == 'bar':
        print(i)

A função index() só devolve a primeira ocorrência, enquanto o enumerate() devolve todas as ocorrências.

Como compreensão da lista:

[i for i, j in enumerate(['foo', 'bar', 'baz']) if j == 'bar']

Aqui está outra pequena solução com itertools.count() (o que é praticamente a mesma abordagem que enumerado):
from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

Isto é mais eficiente para listas maiores do que usar enumerate():

$ python -m timeit -s "from itertools import izip as zip, count" "[i for i, j in zip(count(), ['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 174 usec per loop
$ python -m timeit "[i for i, j in enumerate(['foo', 'bar', 'baz']*500) if j == 'bar']"
10000 loops, best of 3: 196 usec per loop
 457
Author: TerryA, 2017-11-01 23:55:58

Para obter todos os índices:

 indexes = [i for i,x in enumerate(xs) if x == 'foo']
 130
Author: FMc, 2017-12-23 16:43:48

index() devolve o primeiro Índice de valor!

/ Índice(...)
/ L. índice(valor, [iniciar, [parar]]) -> inteiro -- return 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"])
 109
Author: HongboZhu, 2012-03-09 10:38:09

Um problema surgirá se o elemento não estiver na lista. Esta função trata da questão:

# if element is found it returns index of element else returns None

def find_element_in_list(element, list_element):
    try:
        index_element = list_element.index(element)
        return index_element
    except ValueError:
        return None
 67
Author: tanzil, 2017-04-24 10:00:10
a = ["foo","bar","baz",'bar','any','much']

indexes = [index for index in range(len(a)) if a[index] == 'bar']
 58
Author: savinson, 2017-10-31 07:45:46

Tem de definir uma condição para verificar se o elemento que procura está na lista

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None
 40
Author: user3670684, 2014-05-26 04:26:52
Todas as funções propostas aqui reproduzem o comportamento da linguagem inerente, mas obscurecem o que está a acontecer.
[i for i in range(len(mylist)) if mylist[i]==myterm]  # get the indices

[each for each in mylist if each==myterm]             # get the items

mylist.index(myterm) if myterm in mylist else None    # get the first index and fail quietly

Por que escrever uma função com tratamento de exceção se a linguagem fornece os métodos para fazer o que você mesmo quer?

 36
Author: Graham Giller, 2016-12-24 14:24:33

Se quiser todos os índices, então pode usar NumPy:

import numpy as np

array = [1, 2, 1, 3, 4, 5, 1]
item = 1
np_array = np.array(array)
item_index = np.where(np_array==item)
print item_index
# Out: (array([0, 2, 6], dtype=int64),)

É uma solução transparente e legível.

 29
Author: rbrisuda, 2018-06-04 20:26:33

Encontrar o índice de um item com uma lista que o contém em Python

Para uma lista ["foo", "bar", "baz"] e um item na lista "bar", Qual é a maneira mais limpa de obter o seu Índice (1) em Python?

Bem, claro, há o método do índice, que devolve o índice da primeira ocorrência:

>>> l = ["foo", "bar", "baz"]
>>> l.index('bar')
1
Há alguns problemas com este método:
  • Se o valor não estiver na lista, vais ter um ValueError
  • se mais do que um dos o valor está na lista, você só obtém o índice para o primeiro

Sem valores

Se o valor pode estar em falta, tens de apanhar o ValueError.

Pode fazê-lo com uma definição reutilizável como esta:
def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

E usa - o assim:

>>> print(index(l, 'quux'))
None
>>> print(index(l, 'bar'))
1

E o lado negativo disto é que provavelmente terá de verificar se o valor devolvido is ou is not nenhum:

result = index(a_list, value)
if result is not None:
    do_something(result)

Mais de um valor na lista

Se pudesses ter mais ocorrências, você não vai obter informações completas com list.index:

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1
Pode enumerar numa lista os índices:
>>> [index for index, v in enumerate(l) if v == 'bar']
[1, 3]
>>> [index for index, v in enumerate(l) if v == 'boink']
[]

Se não tiver ocorrências, pode verificar isso com uma verificação booleana do resultado, ou simplesmente não fazer nada se repetir os resultados:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)
Melhores dados a mastigar com pandas Se você tem pandas, pode facilmente obter esta informação com um objeto de série:
>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

Uma comparação irá devolver uma série de booleanos:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool
Passa essa série de booleanos para a série através de uma notação subscrita, e recebes apenas os membros correspondentes:
>>> series[series == 'bar']
1    bar
3    bar
dtype: object

Se quiser apenas os índices, o atributo index devolve uma série de inteiros:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')
E se os queres numa lista ou numa tupla, passa-os ao construtor.
>>> list(series[series == 'bar'].index)
[1, 3]
Sim, você poderia usar uma compreensão de lista com enumerado também, mas isso não é tão elegante, na minha opinião-você está fazendo testes para igualdade em Python, em vez de deixar o código builtin escrito em C lidar com ele:
>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]
Isto é um problema XY?

O problema XY é perguntar sobre a sua tentativa de solução em vez do seu problema real.

Porque achas que precisas do Índice dado um elemento numa lista?

Se já sabe o valor, porque se importa onde está numa lista?

Se o valor não está lá, apanhar o {[20] } é bastante verboso - e prefiro evitar isso.

De qualquer forma, costumo estar a ler a lista, por isso vou manter um indicador para qualquer informação interessante, obtendo o índice com enumerado. Se você está munindo dados, você provavelmente deveria estar usando pandas - que tem ferramentas muito mais elegantes do que os simples workarounds Python que eu mostrei. Não me lembro de precisar de mim. No entanto, eu olhei através da Biblioteca Padrão Python, e eu vejo alguns usos excelentes para ele.

Há muitos, muitos usos para ele em idlelib, para o processamento de GUI e texto.

O módulo keyword usa-o para encontrar marcadores de comentários no módulo para regenerar automaticamente a lista de palavras-chave através de metaprogramação.

Em Lib/mailbox.py parece estar a usá-lo como um mapeamento ordenado:

key_list[key_list.index(old)] = new

E

del key_list[key_list.index(key)]

Em Lib/http/cookiejar.py, parece ser usado para obter o próximo mês:

mon = MONTHS_LOWER.index(mon.lower())+1

Em Lib/tarfile.py semelhante aos destilados para obter um cortar para um item:

members = members[:members.index(tarinfo)]

Em Lib/pickletools.py:

numtopop = before.index(markobject)

O que estes usos parecem ter em comum é que eles parecem operar em listas de tamanhos limitados (importante por causa de o(n) Tempo de procura para list.index), e eles são principalmente usados em análise (e UI no caso de OCI).

Embora haja casos de uso para ele, eles são bastante incomuns. Se você se encontrar procurando por esta resposta, pergunte a si mesmo se o que você está fazendo é o uso mais direto das ferramentas fornecido pela língua para o seu caso de uso.

 22
Author: Aaron Hall, 2017-09-02 23:56:20

Todos os índices com o índice zip Função:

get_indexes = lambda x, xs: [i for (y, i) in zip(xs, range(len(xs))) if x == y]

print get_indexes(2, [1, 2, 3, 4, 5, 6, 3, 2, 3, 2])
print get_indexes('f', 'xsfhhttytffsafweef')
 19
Author: Arnaldo P. Figueira Figueira, 2018-06-04 20:50:20

Simplesmente podes ir com

a = [['hand', 'head'], ['phone', 'wallet'], ['lost', 'stock']]
b = ['phone', 'lost']

res = [[x[0] for x in a].index(y) for y in b]
 15
Author: octoback, 2013-05-29 07:17:15

Outra opção

>>> a = ['red', 'blue', 'green', 'red']
>>> b = 'red'
>>> offset = 0;
>>> indices = list()
>>> for i in range(a.count(b)):
...     indices.append(a.index(b,offset))
...     offset = indices[-1]+1
... 
>>> indices
[0, 3]
>>> 
 15
Author: Mathitis2Software, 2013-05-29 19:17:21

Uma variante da resposta do FMc e do user7177 irá dar um dict que pode devolver todos os índices para qualquer entrada:

>>> a = ['foo','bar','baz','bar','any', 'foo', 'much']
>>> l = dict(zip(set(a), map(lambda y: [i for i,z in enumerate(a) if z is y ], set(a))))
>>> l['foo']
[0, 5]
>>> l ['much']
[6]
>>> l
{'baz': [2], 'foo': [0, 5], 'bar': [1, 3], 'any': [4], 'much': [6]}
>>> 

Também pode usar isto como uma linha para obter todos os índices para uma única entrada. Não há garantias de eficiência, embora eu usei set(a) para reduzir o número de vezes que o lambda é chamado.

 13
Author: bvanlew, 2014-03-28 09:11:57
E agora, para algo completamente diferente...

... Como confirmar a existência do item antes de obter o índice. A coisa boa sobre esta abordagem é que a função sempre retorna uma lista de índices -- mesmo que seja uma lista vazia. Também funciona com cordas.

def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    retval = []
    last = 0
    while val in l[last:]:
            i = l[last:].index(val)
            retval.append(last + i)
            last += i + 1   
    return retval

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')

Quando colado numa janela python interactiva:

Python 2.7.6 (v2.7.6:3a1db0d2747e, Nov 10 2013, 00:42:54) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(the_list, val):
...     """Always returns a list containing the indices of val in the_list"""
...     retval = []
...     last = 0
...     while val in the_list[last:]:
...             i = the_list[last:].index(val)
...             retval.append(last + i)
...             last += i + 1   
...     return retval
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 

Actualizar

Depois de mais um ano de desenvolvimento do heads-down python, estou um pouco envergonhado com a minha resposta original, por isso ... defina o registro direito, pode-se certamente usar o código acima; no entanto, a muito a maneira mais idiomática de obter o mesmo comportamento seria usar a compreensão da lista, juntamente com a função enumerate (). Algo do género:
def indices(l, val):
    """Always returns a list containing the indices of val in the_list"""
    return [index for index, value in enumerate(l) if value == val]

l = ['bar','foo','bar','baz','bar','bar']
q = 'bar'
print indices(l,q)
print indices(l,'bat')
print indices('abcdaababb','a')
O que, quando colado numa janela Interactiva em python, produz:
Python 2.7.14 |Anaconda, Inc.| (default, Dec  7 2017, 11:07:58) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> def indices(l, val):
...     """Always returns a list containing the indices of val in the_list"""
...     return [index for index, value in enumerate(l) if value == val]
... 
>>> l = ['bar','foo','bar','baz','bar','bar']
>>> q = 'bar'
>>> print indices(l,q)
[0, 2, 4, 5]
>>> print indices(l,'bat')
[]
>>> print indices('abcdaababb','a')
[0, 4, 5, 7]
>>> 
E agora, depois de rever esta pergunta e todas as respostas, percebi que isto é exatamente o queFMc sugeriu no seu anterior. resposta Na altura em que originalmente respondi a esta pergunta, nem sequer a tinha visto, porque não a entendia. Espero que o meu exemplo um pouco mais descritivo ajude a compreender.

Se a única linha de código acima do still não faz sentido para si, recomendo-lhe vivamente que procure no Google 'compreensão da lista python' e tire alguns minutos para se familiarizar. É apenas um dos muitos recursos poderosos que fazem com que seja uma alegria usar Python para desenvolver codigo.

 13
Author: MrWonderful, 2018-07-18 10:01:05

Obter todas as ocorrências e a posição de um ou mais itens (idênticos) numa lista

Com enumerate (lista) você pode armazenar o primeiro elemento (n) que é o índice da lista quando o elemento x é igual ao que você procura.

>>> alist = ['foo', 'spam', 'egg', 'foo']
>>> foo_indexes = [n for n,x in enumerate(alist) if x=='foo']
>>> foo_indexes
[0, 3]
>>>
Vamos fazer com que a nossa função seja findindex.

Esta função toma o item e a lista como argumentos e devolve a posição do item na lista, como vimos antes.

def indexlist(item2find, list_or_string):
  "Returns all indexes of an item in a list or a string"
  return [n for n,item in enumerate(list_or_string) if item==item2find]

print(indexlist("1", "010101010"))

Saída


[1, 3, 5, 7]

Simples

for n, i in enumerate([1, 2, 3, 4, 1]):
    if i == 1:
        print(n)

Resultado:

0
4
 12
Author: Giovanni Gianni, 2018-06-04 20:28:43

Esta solução não é tão poderosa como as outras, mas se você é um iniciante e só sabe sobre forloops ainda é possível encontrar o primeiro índice de um item, evitando o erro de Valor:

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1
 9
Author: dylankb, 2017-11-12 06:07:52
name ="bar"
list = [["foo", 1], ["bar", 2], ["baz", 3]]
new_list=[]
for item in list:
    new_list.append(item[0])
print(new_list)
try:
    location= new_list.index(name)
except:
    location=-1
print (location)

Isto explica se o texto não está na lista também, se não está na lista então localização = -1

 5
Author: Coder123, 2015-07-05 13:12:19

Uma vez que as listas Python são baseadas em zero, podemos usar a função ZIP built-in da seguinte forma:

>>> [i for i,j in zip(range(len(haystack)), haystack) if j == 'needle' ]

Onde " palheiro "é a lista em questão e" agulha " é o item a procurar.

(Nota: aqui estamos a iterar o uso de i para obter os índices, mas se precisarmos de nos concentrar nos itens, podemos mudar para J.)

 5
Author: jihed gasmi, 2018-06-04 20:56:33
Há uma resposta mais funcional para isto.
list(filter(lambda x: x[1]=="bar",enumerate(["foo", "bar", "baz", "bar", "baz", "bar", "a", "b", "c"])))

Forma mais genérica:

def get_index_of(lst, element):
    return list(map(lambda x: x[0],\
       (list(filter(lambda x: x[1]==element, enumerate(lst))))))
 3
Author: Ankit Gupta, 2018-06-04 20:53:01

O método Python index() lança um erro se o item não foi encontrado, o que é uma treta!

Em vez disso, poderá torná-lo semelhante à função indexOf() do JavaScript que devolve -1 Se o item não foi encontrado:

    try:
        index = array.index('search_keyword')
    except ValueError:
        index = -1
 3
Author: Hamed Baatour, 2018-06-04 20:53:55

Encontrar o índice do item x na lista L:

idx = L.index(x) if (x in L) else -1
 2
Author: Ketan, 2018-05-31 22:46:51
Para aqueles que vêm de outra língua como eu, talvez com um simples loop seja mais fácil de entender e usá-lo:
mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
  if item == "bar":
    print(index, item)
Estou grato por ... Então o que faz o enumerate exatamente?. Isso ajudou-me a entender.
 1
Author: mpoletto, 2018-06-04 20:55:15

Se o desempenho for preocupante:

É mencionado em numerosas respostas que o método embutido de list.index(item) é um algoritmo O(n). Não faz mal se precisares de fazer isto uma vez. Mas se você precisa acessar os índices de elementos uma série de vezes, faz mais sentido primeiro criar um dicionário (O(n)) de pares de índice de itens, e então acessar o índice em O(1) cada vez que você precisar dele.

Se TEM a certeza de que os itens da sua lista nunca são repetidos, pode facilmente:

myList = ["foo", "bar", "baz"]

# Create the dictionary
myDict = dict((e,i) for i,e in enumerate(myList))

# Lookup
myDict["bar"] # Returns 1
# myDict.get("blah") if you don't want an error to be raised if element not found.

Se tiver elementos duplicados e tiver de devolver todos os seus índices:

from collections import defaultdict as dd
myList = ["foo", "bar", "bar", "baz", "foo"]

# Create the dictionary
myDict = dd(list)
for i,e in enumerate(myList):
    myDict[e].append(i)

# Lookup
myDict["foo"] # Returns [0, 4]
 1
Author: FatihAkici, 2018-09-10 18:51:04

Há duas possibilidades se a lista não tiver itens repetidos que é necessário verificar o índice de

 eg: li=[10,20,30] # here need to get index of 20 means
     li.index(20) # will work properly because 20 is not repeated

Se o seu significado repetido lhe dará apenas o primeiro índice

Se precisar de obter todo o índice onde o item está presente significa

eg: li=[10,20,30,20,40, 50, 10] # here need to get index of 20 means its have 2 index (1,3) 

Para conseguir que você precisa fazer isso como

 li=[10,20,30,20,40, 50, 10]
 [i for i, e in enumerate(li) if e == 20]

Então você vai obter uma lista de índice como o / p Como [1,3]

 1
Author: abhi krishnan, 2018-10-04 05:26:17

Como indicado por @TerryA, muitas respostas discutem como encontrar um índice.

more_itertools é uma biblioteca de terceiros com ferramentas para localizar múltiplos índices dentro de um iterável.

Dados

import more_itertools as mit


iterable = ["foo", "bar", "baz", "ham", "foo", "bar", "baz"]

Código

Encontrar índices de observações múltiplas:

list(mit.locate(iterable, lambda x: x == "bar"))
# [1, 5]

Testar vários itens:

list(mit.locate(iterable, lambda x: x in {"bar", "ham"}))
# [1, 3, 5]

Veja também Mais opções com more_itertools.locate. Instalar via > pip install more_itertools.

 0
Author: pylang, 2018-09-25 15:47:56