Localizando o índice de um item em uma lista


3183

Dada uma lista ["foo", "bar", "baz"]e um item na lista "bar", como obtenho seu index ( 1) no Python?


6
Você está retornando: [1] O índice mais baixo, caso haja várias instâncias de "bar", [2] Todos os índices de "bar"?
Ểơửṩgǻňạcểơửṩ

4
a) É garantido que o item esteja na lista ou como devemos lidar com o caso de erro? (retornar None / raise ValueError) b) As entradas da lista são garantidas como únicas e devemos retornar o primeiro índice de uma correspondência ou todos os índices?
smci 21/05

Veja as respostas com integração numpy, matrizes numpy são muito mais eficientes do que as listas Python. Se a lista é curta, não há problema em copiá-la de uma lista Python; se não for, talvez você deva considerar o armazenamento dos elementos em um array numpy em primeiro lugar.
Athanassios 28/01

Respostas:


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

Referência: Estruturas de Dados> Mais sobre Listas

Seguem as advertências

Note-se que, enquanto esta é talvez a maneira mais limpa para responder à pergunta como pediu , indexé um componente bastante fraco da listAPI, e eu não me lembro a última vez que eu usei com raiva. Nos comentários me foi indicado que, como essa resposta é fortemente referenciada, ela deve ser mais completa. Algumas advertências sobre list.indexseguir. Provavelmente vale a pena dar uma olhada inicialmente na documentação:

list.index(x[, start[, end]])

Retorne o índice baseado em zero na lista do primeiro item cujo valor é igual a x . Gera a ValueErrorse não houver esse item.

Os argumentos opcionais start e end são interpretados como na notação de fatia e são usados ​​para limitar a pesquisa a uma subsequência específica da lista. O índice retornado é calculado em relação ao início da sequência completa, em vez do argumento start.

Complexidade de tempo linear no tamanho da lista

Uma indexchamada verifica todos os elementos da lista em ordem, até encontrar uma correspondência. Se sua lista for longa e você não souber aproximadamente onde ela ocorre, essa pesquisa poderá se tornar um gargalo. Nesse caso, você deve considerar uma estrutura de dados diferente. Observe que, se você souber aproximadamente onde encontrar a correspondência, poderá dar indexuma dica. Por exemplo, neste trecho, l.index(999_999, 999_990, 1_000_000)é aproximadamente cinco ordens de magnitude mais rápido que o direito l.index(999_999), porque o primeiro precisa pesquisar apenas 10 entradas, enquanto o último 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

Retorna apenas o índice da primeira correspondência ao argumento

Uma chamada para indexpesquisar na lista em ordem até encontrar uma correspondência e parar por aí. Se você espera precisar de índices de mais correspondências, use uma compreensão de lista ou expressão geradora.

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

Na maioria dos lugares onde antes eu usaria index, agora uso uma compreensão de lista ou expressão geradora, porque são mais generalizáveis. Portanto, se você está pensando em indexprocurar, dê uma olhada nesses excelentes recursos Python.

Lança se o elemento não estiver presente na lista

Uma chamada para indexresultados em a ValueErrorse 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 não estiver presente na lista, você deve

  1. Verifique primeiro com item in my_list(abordagem limpa e legível) ou
  2. Envolva a indexchamada em um try/exceptbloco que atenda ValueError(provavelmente mais rápido, pelo menos quando a lista a pesquisar for longa e o item estiver geralmente presente).

20
index retorna o primeiro item cujo valor é "bar". Se a "barra" existir duas vezes na lista, você nunca encontrará a chave para a segunda "barra". Veja a documentação: docs.python.org/3/tutorial/datastructures.html
mpoletto

2
Se você está procurando apenas um elemento (o primeiro), descobri que index()é pouco menos de 90% mais rápido que a compreensão de listas em relação a listas de números inteiros.
slybloty

Qual estrutura de dados deve ser usada se a lista for muito longa?
izhang05 22/02

@izhang: Algum índice auxiliar, como um ditado {element -> list_index}, se os elementos são hashable e a posição na lista é importante.
Alex Coventry

899

Uma coisa que é realmente útil no aprendizado 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 geralmente o levará ao método que você está procurando.


2
O bpython é uma maneira agradável e amigável de ler os documentos de maneira interativa.
goetzc 22/09/19

@davidavr sim, mas o resto de nós, que apenas deseja pesquisar no Google em vez de percorrer os documentos de ajuda, não teria esse bom conjunto central de opções. :)
honkaboy 6/04

556

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

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

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

Como compreensão da lista:

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

Aqui também está outra solução pequena itertools.count()(que é praticamente a mesma abordagem que enumerar):

from itertools import izip as zip, count # izip for maximum efficiency
[i for i, j in zip(count(), ['foo', 'bar', 'baz']) if j == 'bar']

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

A enumeração funciona melhor do que os métodos baseados em índice para mim, pois estou procurando reunir os índices de seqüências de caracteres usando 'beginwith "e preciso reunir várias ocorrências. Ou existe uma maneira de usar o índice com" beginwith "que eu não conseguia descobrir
Tupelo Thistlehead

3
Nas minhas mãos, a versão enumerada é consistentemente um pouco mais rápida. Alguns detalhes da implementação podem ter sido alterados desde que a medição acima foi lançada.
Alex Coventry

2
Isso já foi respondido desde '11: stackoverflow.com/questions/6294179/…
Cristik 10/02/19


132

index()retorna o primeiro índice de valor!

| índice (...)
| L.index (valor, [iniciar, [parar]]) -> inteiro - retorna o primeiro índice do 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"])

2
E se não existir na lista?
Peter Mortensen

1
Item inexistente aumentará ValueError
Nam G VU

1
Essa resposta se encaixaria melhor aqui: stackoverflow.com/questions/6294179/...
Cristik

86

Surgirá um problema se o elemento não estiver na lista. Esta função lida com o problema:

# 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


58

Você precisa definir uma condição para verificar se o elemento que você está pesquisando está na lista

if 'your_element' in mylist:
    print mylist.index('your_element')
else:
    print None

1
Isso nos ajuda a evitar tentar pegar!
Devssh # /

No entanto, isso pode dobrar a complexidade. Alguém checou?
stefanct 6/09/19

@stefanct A complexidade do tempo ainda é linear, mas irá percorrer a lista duas vezes.
ApproachingDarknessFish

@ApproachingDarknessFish Isso é obviamente o que eu quis dizer. Mesmo que pedanticamente seja a mesma ordem de complexidade, a repetição da iteração pode ser uma grande desvantagem em muitos casos de uso. E ainda não sabemos a resposta ...
stefanct

44

Todas as funções propostas aqui reproduzem o comportamento inerente da linguagem, mas obscurecem o que está acontecendo.

[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 manipulação de exceção se a linguagem fornece os métodos para fazer o que você deseja?


9
O terceiro método itera duas vezes na lista, certo?
Eric Duminil

Re: "Todas as funções propostas aqui" : No momento em que escrevo, talvez, mas você deve verificar as respostas mais recentes para ver se ainda é verdade.
Peter Mortensen

41

Se você deseja todos os índices, pode usar o 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 clara e legível.


4
E as listas de strings, listas de objetos não numéricos, etc ...?
Laryx Decidua

1
Esta resposta deve ser melhor postada aqui: stackoverflow.com/questions/6294179/…
Cristik

1
Este é o melhor que eu já li. matrizes numpy são muito mais eficientes do que as listas Python. Se a lista é curta, não há problema em copiá-la de uma lista Python, se não for, talvez o desenvolvedor deva considerar o armazenamento dos elementos em um array numpy em primeiro lugar.
Athanassios 28/01

35

Localizando o índice de um item, dada uma lista que o contém em Python

Para uma lista ["foo", "bar", "baz"]e um item da lista "bar", qual é a maneira mais limpa de obter seu índice (1) no Python?

Bem, claro, existe o método index, que retorna o índice da primeira ocorrência:

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

Existem alguns problemas com este método:

  • se o valor não estiver na lista, você receberá uma ValueError
  • se mais de um valor estiver na lista, você obtém apenas o índice do primeiro

Sem valores

Se o valor estiver faltando, você precisará capturar o ValueError.

Você pode fazer isso com uma definição reutilizável como esta:

def index(a_list, value):
    try:
        return a_list.index(value)
    except ValueError:
        return None

E use-o assim:

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

E a desvantagem disso é que você provavelmente verificará se o valor retornado isou is notNenhum:

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

Mais de um valor na lista

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

>>> l.append('bar')
>>> l
['foo', 'bar', 'baz', 'bar']
>>> l.index('bar')              # nothing at index 3?
1

Você pode enumerar em uma 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 você não tiver ocorrências, poderá verificar isso com verificação booleana do resultado ou simplesmente não fazer nada se fizer um loop sobre os resultados:

indexes = [index for index, v in enumerate(l) if v == 'boink']
for index in indexes:
    do_something(index)

Melhor munging de dados com pandas

Se você tem pandas, pode facilmente obter essas informações com um objeto Series:

>>> import pandas as pd
>>> series = pd.Series(l)
>>> series
0    foo
1    bar
2    baz
3    bar
dtype: object

Uma verificação de comparação retornará uma série de booleanos:

>>> series == 'bar'
0    False
1     True
2    False
3     True
dtype: bool

Passe essa série de booleanos para a série por meio de notação subscrita e você obterá apenas os membros correspondentes:

>>> series[series == 'bar']
1    bar
3    bar
dtype: object

Se você deseja apenas os índices, o atributo index retorna uma série de números inteiros:

>>> series[series == 'bar'].index
Int64Index([1, 3], dtype='int64')

E se você os quiser em uma lista ou tupla, apenas passe-os para o construtor:

>>> list(series[series == 'bar'].index)
[1, 3]

Sim, você também pode usar uma compreensão de lista com enumerar, mas isso não é tão elegante, na minha opinião - você está fazendo testes de igualdade em Python, em vez de permitir que o código interno escrito em C lide com isso:

>>> [i for i, value in enumerate(l) if value == 'bar']
[1, 3]

Este é um problema XY ?

O problema XY é perguntar sobre sua tentativa de solução, e não sobre o seu problema real.

Por que você acha que precisa do índice com um elemento em uma lista?

Se você já conhece o valor, por que se importa onde ele está em uma lista?

Se o valor não estiver lá, pegar o ValueErroré bastante detalhado - e prefiro evitar isso.

De qualquer maneira, eu estou repetindo a lista de qualquer maneira, por isso usualmente apontarei para qualquer informação interessante, obtendo o índice com enumerate.

Se você estiver pesquisando dados, provavelmente deve usar pandas - que tem ferramentas muito mais elegantes do que as soluções puras de Python que mostrei.

Não me lembro de precisar list.index, eu mesmo. No entanto, examinei a biblioteca padrão do Python e vejo alguns usos excelentes para ela.

Existem muitos, muitos usos para isso idlelib, na GUI e na análise de texto.

o keyword módulo o utiliza para encontrar marcadores de comentários no módulo para regenerar automaticamente a lista de palavras-chave nele por metaprogramação.

No Lib / mailbox.py, parece 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

No Lib / tarfile.py, semelhante ao distutils, para obter uma fatia de um item:

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

Em Lib / pickletools.py:

numtopop = before.index(markobject)

O que esses usos parecem ter em comum é que eles parecem operar em listas de tamanhos restritos (importante por causa do tempo de pesquisa de O (n) list.index ) e são usados ​​principalmente na análise (e na interface do usuário no caso de inatividade).

Embora existam casos de uso para isso, eles são bastante incomuns. Se você encontrar essa resposta, pergunte-se se o que está fazendo é o uso mais direto das ferramentas fornecidas pelo idioma para o seu caso de uso.



21

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

Com enumerate (alist), 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 nossa função findindex

Essa função pega o item e a lista como argumentos e retorna a posição do item na lista, como vimos anteriormente.

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

Resultado


[1, 3, 5, 7]

Simples

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

Resultado:

0
4

1
Esta resposta deve ser melhor postada aqui: stackoverflow.com/questions/6294179/…
Cristik

16

Simplesmente você pode 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

E agora para algo completamente diferente...

... como confirmar a existência do item antes de obter o índice. O bom dessa abordagem é que a função sempre retorna uma lista de índices - mesmo que seja uma lista vazia. Também funciona com strings.

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 em uma janela python interativa:

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

Atualizar

Depois de mais um ano de desenvolvimento python, estou um pouco envergonhado com a minha resposta original; portanto, para esclarecer as coisas, certamente é possível usar o código acima; no entanto, a maneira muito mais idiomática de obter o mesmo comportamento seria usar a compreensão da lista, junto com a função enumerate ().

Algo assim:

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

Que, quando colado em uma janela python interativa, gera:

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 revisar esta pergunta e todas as respostas, percebo que é exatamente isso que o FMc sugeriu em sua resposta anterior . No momento em que originalmente respondi a essa pergunta, eu nem vi , porque não a entendi. Espero que meu exemplo um pouco mais detalhado ajude a entender.

Se a única linha de código acima ainda não faz sentido para você, recomendo que você compreenda a lista de python do Google e reserve alguns minutos para se familiarizar. É apenas um dos muitos recursos poderosos que tornam uma alegria usar o Python para desenvolver código.


12

Uma variante na resposta do FMc e user7177 fornecerá um ditado que pode retornar 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]}
>>> 

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


1
Esta resposta deve ser melhor postada aqui: stackoverflow.com/questions/6294179/…
Cristik

10

Essa solução não é tão poderosa quanto outras, mas se você é iniciante e conhece apenas os forloops, ainda é possível encontrar o primeiro índice de um item, evitando o ValueError:

def find_element(p,t):
    i = 0
    for e in p:
        if e == t:
            return i
        else:
            i +=1
    return -1

9

Localizando o índice do item x na lista L:

idx = L.index(x) if (x in L) else -1

4
Isso itera a matriz duas vezes, portanto, pode resultar em problemas de desempenho para matrizes grandes.
Cristik

Aceita. Se as listas forem consideravelmente longas, eu optaria por outra coisa. Não deve ser um grande problema para listas pequenas e médias.
Ketan

5

Como as listas Python são baseadas em zero, podemos usar a função interna zip da seguinte maneira:

>>> [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 ser procurado.

(Observação: aqui estamos iterando usando i para obter os índices, mas se precisarmos nos concentrar nos itens, podemos mudar para j.)


3
[i para i, j enumerar (palheiro) se j == 'agulha'] é mais compacto e legível, eu acho.
Giovanni G. PY

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

Isso explica se a string também não está na lista, se não estiver na lista, location = -1


4

O index()método Python gera um erro se o item não foi encontrado. Portanto, você pode torná-lo semelhante à indexOf()função do JavaScript, que retorna -1se o item não foi encontrado:

try:
    index = array.index('search_keyword')
except ValueError:
    index = -1

5
no entanto, o JavaScript tem a filosofia de que resultados estranhos são melhores que erros; portanto, faz sentido retornar -1, mas no Python pode ser difícil rastrear um bug, já que -1 retorna um item do final da lista.
Sapphire_Brick

3

Há uma resposta mais funcional para isso.

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

1
Essa resposta se sente em casa para Scala/ funcionais de programação entusiastas
y2k-shubham

3

Vamos dar o nome lstà lista que você possui. Pode-se converter a lista lstpara a numpy array. E, em seguida, use numpy.where para obter o índice do item escolhido na lista. A seguir está a maneira pela qual você o implementará.

import numpy as np

lst = ["foo", "bar", "baz"]  #lst: : 'list' data type
print np.where( np.array(lst) == 'bar')[0][0]

>>> 1

2

Para quem vem de outro idioma como eu, talvez com um loop simples seja mais fácil entender e usá-lo:

mylist = ["foo", "bar", "baz", "bar"]
newlist = enumerate(mylist)
for index, item in newlist:
  if item == "bar":
    print(index, item)

Sou grato por Então, o que exatamente enumerar faz? . Isso me ajudou a entender.


2

Se você vai encontrar um índice uma vez, então o método "index" é bom. No entanto, se você deseja pesquisar seus dados mais de uma vez, recomendo o uso do módulo bisect . Lembre-se de que os dados do módulo bisect devem ser classificados. Assim, você classifica os dados uma vez e depois pode usar a divisão. O uso do módulo bisect na minha máquina é cerca de 20 vezes mais rápido do que o método index.

Aqui está um exemplo de código usando a sintaxe Python 3.8 e acima:

import bisect
from timeit import timeit

def bisect_search(container, value):
    return (
      index 
      if (index := bisect.bisect_left(container, value)) < len(container) 
      and container[index] == value else -1
    )

data = list(range(1000))
# value to search
value = 666

# times to test
ttt = 1000

t1 = timeit(lambda: data.index(value), number=ttt)
t2 = timeit(lambda: bisect_search(data, value), number=ttt)

print(f"{t1=:.4f}, {t2=:.4f}, diffs {t1/t2=:.2f}")

Resultado:

t1=0.0400, t2=0.0020, diffs t1/t2=19.60

1

Se o desempenho for motivo de preocupação:

É mencionado em numerosas respostas que o método incorporado de list.index(item) método é um algoritmo O (n). Tudo bem se você precisar fazer isso uma vez. Mas se você precisar acessar os índices dos elementos várias vezes, faz mais sentido criar primeiro um dicionário (O (n)) de pares de índice de itens e, em seguida, acessar o índice em O (1) toda vez que precisar isto.

Se você tiver certeza de que os itens da sua lista nunca serão repetidos, poderá 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 você pode ter elementos duplicados e precisar retornar 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

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

more_itertoolsé uma biblioteca de terceiros com ferramentas para localizar vários índices em um iterável.

Dado

import more_itertools as mit


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

Código

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

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

Teste 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. Instale via > pip install more_itertools.


0

usando o dicionário, onde processa a lista primeiro e depois adiciona o índice a ela

from collections import defaultdict

index_dict = defaultdict(list)    
word_list =  ['foo','bar','baz','bar','any', 'foo', 'much']

for word_index in range(len(word_list)) :
    index_dict[word_list[word_index]].append(word_index)

word_index_to_find = 'foo'       
print(index_dict[word_index_to_find])

# output :  [0, 5]

-1

na minha opinião o ["foo", "bar", "baz"].index("bar")é bom, mas não é suficiente! porque se "bar" não estiver no dicionário, ValueErrorelevado . Então você pode usar esta função:

def find_index(arr, name):
    try:
        return arr.index(name)
    except ValueError:
        return -1

if __name__ == '__main__':
    print(find_index(["foo", "bar", "baz"], "bar"))

e o resultado é:

1

e se o nome não estava em arr, a função retornará -1. por exemplo:

print (find_index (["foo", "bar", "baz"], "fooo"))

-1


1
Não use isso porque l = [1, 2]; find_index(l, 3)retornaria -1e l[find_index(l, 3)]retornaria 2. -1 é uma coisa ruim para retornar, basta retornar None.
Daniel Stracaboško

-1 é um contrato que você pode devolver o que quiser, mas tente usar o Lesser None menor em seus programas, porque None ou Null na comunicação do seu programa com outros programas, como sites Android e PHP, podem causar interrupção do programa, por exemplo, você pode retornar nulo em JSON e o aplicativo de telefone do site será fechado ou retornará o Erro 500 (erro interno do servidor).
NaabNuts 13/03
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.