Python usando la comprensión de enumerar dentro de la lista


125

Supongamos que tengo una lista como esta:

mylist = ["a","b","c","d"]

Para obtener los valores impresos junto con su índice, puedo usar la enumeratefunción de Python como esta

>>> for i,j in enumerate(mylist):
...     print i,j
...
0 a
1 b
2 c
3 d
>>>

Ahora, cuando trato de usarlo dentro de un list comprehensionme da este error

>>> [i,j for i,j in enumerate(mylist)]
  File "<stdin>", line 1
    [i,j for i,j in enumerate(mylist)]
           ^
SyntaxError: invalid syntax

Entonces, mi pregunta es: ¿cuál es la forma correcta de usar la comprensión de enumerar dentro de la lista?

Respuestas:


166

Prueba esto:

[(i, j) for i, j in enumerate(mylist)]

Debes poner i,jdentro de una tupla para que la comprensión de la lista funcione. Alternativamente, dado que enumerate() ya devuelve una tupla, puede devolverla directamente sin desempaquetarla primero:

[pair for pair in enumerate(mylist)]

De cualquier manera, el resultado que se devuelve es el esperado:

> [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

44
No es obligatorio ser una tupla. Cualquier expresión que use i y j que devuelva un valor funcionará
Alvaro

uso de enumeración es grande, ¿qué hay de lo que hace más eficiente el uso de itertools
Pramit

3
Sólo recuerde que una tupla es construido por el , no al (). "Poner i,jdentro de una tupla" no tiene sentido, ¡ya que i,jes una tupla! El problema es que el analizador de listas de compilación necesita los parens para el grupo de instrucciones.
cowbert

46

Para ser realmente claro, esto no tiene nada que ver enumeratey todo que ver con la sintaxis de comprensión de listas.

Esta comprensión de la lista devuelve una lista de tuplas:

[(i,j) for i in range(3) for j in 'abc']

esta es una lista de dictados:

[{i:j} for i in range(3) for j in 'abc']

una lista de listas:

[[i,j] for i in range(3) for j in 'abc']

Un error de sintaxis:

[i,j for i in range(3) for j in 'abc']

Lo cual es inconsistente (en mi humilde opinión) y confuso con la sintaxis de comprensión del diccionario:

>>> {i:j for i,j in enumerate('abcdef')}
{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e', 5: 'f'}

Y un conjunto de tuplas:

>>> {(i,j) for i,j in enumerate('abcdef')}
set([(0, 'a'), (4, 'e'), (1, 'b'), (2, 'c'), (5, 'f'), (3, 'd')])

Como dijo Óscar López, puede pasar la tupla de enumeración directamente:

>>> [t for t in enumerate('abcdef') ] 
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd'), (4, 'e'), (5, 'f')]

32

O, si no insiste en usar una lista de comprensión:

>>> mylist = ["a","b","c","d"]
>>> list(enumerate(mylist))
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

12

Si está utilizando listas largas, parece que la comprensión de la lista es más rápida, sin mencionar que es más legible.

~$ python -mtimeit -s"mylist = ['a','b','c','d']" "list(enumerate(mylist))"
1000000 loops, best of 3: 1.61 usec per loop
~$ python -mtimeit -s"mylist = ['a','b','c','d']" "[(i, j) for i, j in enumerate(mylist)]"
1000000 loops, best of 3: 0.978 usec per loop
~$ python -mtimeit -s"mylist = ['a','b','c','d']" "[t for t in enumerate(mylist)]"
1000000 loops, best of 3: 0.767 usec per loop

2
+1 No lo probé, pero apuesto a que [t for t in enumerate(my list)]es aún más rápido.
el lobo

11

Aquí hay una manera de hacerlo:

>>> mylist = ['a', 'b', 'c', 'd']
>>> [item for item in enumerate(mylist)]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

Alternativamente, puedes hacer:

>>> [(i, j) for i, j in enumerate(mylist)]
[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]

La razón por la que obtuvo un error fue porque le faltaba el () iy jpara convertirlo en una tupla.



0

Toda gran respuesta chicos. Sé que la pregunta aquí es específica para la enumeración, pero ¿qué tal algo como esto, solo otra perspectiva?

from itertools import izip, count
a = ["5", "6", "1", "2"]
tupleList = list( izip( count(), a ) )
print(tupleList)

Se vuelve más poderoso, si uno tiene que iterar múltiples listas en paralelo en términos de rendimiento. Solo un pensamiento

a = ["5", "6", "1", "2"]
b = ["a", "b", "c", "d"]
tupleList = list( izip( count(), a, b ) )
print(tupleList)
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.