¿Cómo obtener la posición del artículo en una lista?


169

Estoy iterando sobre una lista y quiero imprimir el índice del elemento si cumple una determinada condición. ¿Cómo haría esto?

Ejemplo:

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

Respuestas:


280

Hmmm Hubo una respuesta con una lista de comprensión aquí, pero desapareció.

Aquí:

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

Ejemplo:

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

Actualizar:

Bien, si quieres una expresión generadora, tendremos una expresión generadora. Aquí está la lista de comprensión nuevamente, en un ciclo for:

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

Ahora construiremos un generador ...

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

y lo suficientemente ingenioso, podemos asignar eso a una variable, y usarlo desde allí ...

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

Y pensar que solía escribir FORTRAN.


66
Después de probablemente 25 años de cuestionar la programación funcional, creo que finalmente estoy obteniendo la pista. lista de comprensión es da bomb.
Charlie Martin

15
Supongo que quiere decir "letra única" y, francamente, un nombre más largo en este ejemplo no tendría más contenido de información.
Charlie Martin

2
Gracias por una gran respuesta Creo que el comentario de @ nailer podría estar relacionado con el hecho de que use 'i' en dos contextos diferentes en una sola línea en el ejemplo del generador; uno dentro de la comprensión y el otro para recorrerlo. Sé que me tiró por un segundo.
Brown

1
@CharlieMartin Utiliza 'i' para el índice en lugar del elemento según la convención común para variables de un solo carácter. Nombrar el índice 'índice' y el elemento 'elemento' eliminaría la ambigüedad. Además, está respondiendo a un padre que usó 'elemento' y 'posición' y es de buena educación no renombrar innecesariamente partes del código original en su respuesta.
mikemaccana

1
Súper sintaxis: o) Puede obtener fácilmente un parámetro de línea de comando. Deje que hay una serie de argumentos: args = ['x', '-p1', 'v1', '-p2', 'v2']. Entonces el comando args[[i for i, x in enumerate(args) if x == '-p1'][0] + 1]regresa'v1'
Theodor Keinstein

170

¿Qué pasa con lo siguiente?

print testlist.index(element)

Si no está seguro de si el elemento a buscar está realmente en la lista, puede agregar una verificación preliminar, como

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

o

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

o la "forma pitónica", que no me gusta mucho porque el código es menos claro, pero a veces es más eficiente,

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

55
en lugar de realizar una prueba antes de acceder, también puede probar y verificarValueError
kratenko

Creo que él quiere encontrar todos los sucesos, parece que solo das el primero.
tfv

@tfv No veo cómo puede llegar a tal conclusión ya que la pregunta dice "elemento" y no "elementos".
mmj

40

Use enumerate:

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 en lugar de rango según lo solicitado (ver comentarios).


reemplace range () con xrange () - range () crea una lista, xrange () crea un iterador. xrange () usa mucho menos memoria, y la llamada inicial es más rápida.
gnud

2
Estoy de acuerdo con las listas grandes en los programas de python 2. Sin embargo, tenga en cuenta que 'rango' seguirá funcionando en python 3 (y funcionará como xrange IIRC). 'xrange' sigue el camino de los dinosaurios.
jakber

2
Actualización: xrangese depraga en Python 3.x, ya que lo nuevo rangees lo viejoxrange
tim-oh

5

Aquí hay otra forma de hacer esto:

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


2

Prueba lo siguiente:

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

Si su lista se hizo lo suficientemente grande y solo esperaba encontrar el valor en un número escaso de índices, considere que este código podría ejecutarse mucho más rápido porque no tiene que repetir cada valor en la 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

Si espera encontrar mucho el valor, probablemente debería agregar "índice" a una lista e imprimir la lista al final para ahorrar tiempo por iteración.


Hice algunas pruebas de tiempo. La técnica de comprensión de la lista se ejecuta un 38% más rápido que este código. (Reemplacé su declaración de impresión con una llamada outputlist.append)
Deestan

También hice algunas pruebas con tamaños de lista de 100000 valores aleatorios entre 1 y 100. El código que escribí fue en algunos casos el doble de rápido. Ninguna prueba de tiempo es comparable a la aplicación del afiche (deben probarse a sí mismos para asegurarse, por supuesto). Pido disculpas si mi opinión fue perjudicial para esta publicación.

0

Creo que podría ser útil utilizar el método curselection () de la biblioteca Tkinter:

from Tkinter import * 
listbox.curselection()

Este método funciona en los widgets de cuadro de lista de Tkinter, por lo que deberá construir uno de ellos en lugar de una lista.

Esto devolverá una posición como esta:

('0',) (aunque las versiones posteriores de Tkinter pueden devolver una lista de entradas)

Cuál es para la primera posición y el número cambiará de acuerdo con la posición del artículo.

Para obtener más información, consulte esta página: http://effbot.org/tkinterbook/listbox.htm

Saludos.


1
Idea interesante. Sin embargo, dado que esto requiere importar toda la biblioteca de Tkinter, no es la forma más eficiente de resolver el problema.
seaotternerd

3
Este es un camino tan ineficiente y sinuoso que diría que es una respuesta incorrecta, incluso si de alguna manera aborda la pregunta.

Esta respuesta no tiene nada que ver con la pregunta.
Cody Piersall

0

¿Por qué complicar las cosas?

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

0

Solo para ilustrar el ejemplo completo junto con el input_listque tiene searies1(ejemplo: input_list [0]) en el que desea hacer una búsqueda series2(ejemplo: input_list [1]) y obtener índices de series2 si existen en series1.

Nota: Tu certain conditionirá en expresión lambda si las condiciones son 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)

salida:

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

Supongo que es exactamente lo que quieres. ;-) 'id' será siempre el índice de los valores en la lista.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.