Como obter a posição do item em uma lista?


169

Estou repetindo uma lista e quero imprimir o índice do item, se ele atender a uma determinada condição. Como eu faria isso?

Exemplo:

testlist = [1,2,3,5,3,1,2,1,6]
for item in testlist:
    if item == 1:
        print position

Respostas:


280

Hummm. Houve uma resposta com uma compreensão da lista aqui, mas ela desapareceu.

Aqui:

 [i for i,x in enumerate(testlist) if x == 1]

Exemplo:

>>> testlist
[1, 2, 3, 5, 3, 1, 2, 1, 6]
>>> [i for i,x in enumerate(testlist) if x == 1]
[0, 5, 7]

Atualizar:

Ok, você quer uma expressão geradora, teremos uma expressão geradora. Aqui está a compreensão da lista novamente, em um loop for:

>>> for i in [i for i,x in enumerate(testlist) if x == 1]:
...     print i
... 
0
5
7

Agora vamos construir um gerador ...

>>> (i for i,x in enumerate(testlist) if x == 1)
<generator object at 0x6b508>
>>> for i in (i for i,x in enumerate(testlist) if x == 1):
...     print i
... 
0
5
7

e de maneira bastante inteligente, podemos atribuir isso a uma variável e usá-la a partir daí ...

>>> gen = (i for i,x in enumerate(testlist) if x == 1)
>>> for i in gen: print i
... 
0
5
7

E pensar que eu costumava escrever FORTRAN.


6
Depois de provavelmente 25 anos questionando a programação funcional, acho que finalmente entendi. a compreensão da lista é da bomba.
Charlie Martin

15
Presumo que você queira dizer "letra única" e, francamente, um nome mais longo neste exemplo não teria mais conteúdo informativo.
Charlie Martin

2
Obrigado pela ótima resposta. Eu acho que o comentário do @ nailer pode estar relacionado ao fato de você usar 'i' em dois contextos diferentes em uma única linha no exemplo do gerador; um dentro da compreensão e o outro para iterar através dela. Eu sei que isso me excitou por um segundo.
Brown

1
@CharlieMartin Você usa 'i' para o índice em vez do item, de acordo com uma convenção comum para variáveis ​​de caractere único. Nomear o índice 'index' e o item 'item' removeriam a ambiguidade. Além disso, você está respondendo a um pai que usou 'item' e 'position' e é uma boa maneira de não renomear desnecessariamente partes do código original em sua resposta.
Mikemaccana

1
Super sintaxe: o) Você pode facilmente obter um parâmetro de linha de comando. Vamos existe uma matriz de argumentos: args = ['x', '-p1', 'v1', '-p2', 'v2']. Em seguida, o comando args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]retorna'v1'
Theodor Keinstein 15/08/14

170

E o que se segue?

print testlist.index(element)

Se você não tiver certeza se o elemento a procurar está realmente na lista, adicione uma verificação preliminar, como

if element in testlist:
    print testlist.index(element)

ou

print(testlist.index(element) if element in testlist else None)

ou a "maneira pitônica", da qual não gosto muito porque o código é menos claro, mas às vezes é mais eficiente,

try:
    print testlist.index(element)
except ValueError:
    pass

5
em vez de testar antes de acessar, você também pode apenas tentar e verificar se háValueError
kratenko

Eu acho que ele quer encontrar todas as ocorrências, você parece dar apenas a primeira.
TFV

@tfv Não vejo como você pode chegar a essa conclusão, pois a pergunta diz "item" e não "itens".
MMJ

40

Use enumerar:

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

10
for i in xrange(len(testlist)):
  if testlist[i] == 1:
    print i

xrange em vez do intervalo, conforme solicitado (ver comentários).


substituir range () por xrange () - range () cria uma lista, xrange () cria um iterador. O xrange () usa menos memória e a chamada inicial é mais rápida.
gnud

2
Eu concordo com listas grandes em programas python 2. Observe que 'range' ainda funcionará no python 3 (e funciona como xrange IIRC). 'xrange' está seguindo o caminho dos dinossauros.
jakber

2
Atualização: xrangeé preterido no Python 3.x, pois o novo rangeé o antigoxrange
tim-oh

5

Aqui está outra maneira de fazer isso:

try:
   id = testlist.index('1')
   print testlist[id]
except ValueError:
   print "Not Found"


2

Experimente o abaixo:

testlist = [1,2,3,5,3,1,2,1,6]    
position=0
for i in testlist:
   if i == 1:
      print(position)
   position=position+1

1

Se sua lista ficou grande o suficiente e você esperava encontrar apenas o valor em um número escasso de índices, considere que esse código poderia ser executado muito mais rapidamente, porque você não precisa iterar todos os valores da lista.

lookingFor = 1
i = 0
index = 0
try:
  while i < len(testlist):
    index = testlist.index(lookingFor,i)
    i = index + 1
    print index
except ValueError: #testlist.index() cannot find lookingFor
  pass

Se você espera encontrar muito o valor, provavelmente deve anexar "index" a uma lista e imprimi-la no final para economizar tempo por iteração.


Eu fiz alguns testes de tempo. A técnica de compreensão da lista é executada 38% mais rápido que esse código. (I substituiu a sua declaração de impressão com uma chamada outputlist.append)
Deestan

Também fiz alguns testes com tamanhos de lista de 100000 valores aleatórios entre 1 e 100. O código que escrevi foi, em alguns casos, duas vezes mais rápido. Nenhum teste de tempo é comparável ao aplicativo do pôster (eles devem se testar para ter certeza, é claro). Peço desculpas se minha opinião foi prejudicial para este post.

0

Eu acho que pode ser útil usar o método curselection () da biblioteca Tkinter:

from Tkinter import * 
listbox.curselection()

Esse método funciona nos widgets da caixa de listagem do Tkinter, portanto, você precisará construir um deles em vez de uma lista.

Isso retornará uma posição como esta:

('0',) (embora versões posteriores do Tkinter possam retornar uma lista de entradas)

Qual é a primeira posição e o número será alterado de acordo com a posição do item.

Para mais informações, consulte esta página: http://effbot.org/tkinterbook/listbox.htm

Saudações.


1
Idéia interessante. Como isso requer a importação de toda a biblioteca Tkinter, porém, não é a maneira mais eficiente de resolver o problema.
seaotternerd

3
Esse é um caminho tão ineficiente e sinuoso que eu diria que é uma resposta errada, mesmo que de algum modo resolva a questão.

Esta resposta não tem nada a ver com a pergunta.
precisa saber é o seguinte

0

Por que complicar as coisas?

testlist = [1,2,3,5,3,1,2,1,6]
for position, item in enumerate(testlist):
    if item == 1:
        print position

0

Apenas para ilustrar um exemplo completo, juntamente com o input_listque possui searies1(exemplo: input_list [0]) no qual você deseja fazer uma pesquisa series2(exemplo: input_list [1]) e obter índices da série2, se existir na série1.

Nota: Você certain conditionirá na expressão lambda se as condições forem simples

input_list = [[1,2,3,4,5,6,7],[1,3,7]]
series1 = input_list[0]
series2 = input_list[1]
idx_list = list(map(lambda item: series1.index(item) if item in series1 else None, series2))
print(idx_list)

resultado:

[0, 2, 6]

-2
testlist = [1,2,3,5,3,1,2,1,6]
for id, value in enumerate(testlist):
    if id == 1:
        print testlist[id]

Eu acho que é exatamente o que você quer. ;-) 'id' sempre será o índice dos valores na lista.

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.