Más sobre comprensión de listas: continuación
Mira el ejemplo en el editor.
Compacidad y elegancia: estas dos palabras vienen a la mente al mirar el código.
Entonces, ¿qué tienen en común, generadores y listas de comprensión? ¿Hay alguna conexión entre ellos? Sí. Una conexión algo suelta, pero inequívoca.
Solo un cambio puede convertir cualquier comprensión en un generador.
Ahora mira el código a continuación y ve si puedes encontrar el detalle que convierte una comprensión de la lista en un generador:
lst = [1 if x % 2 == 0 else 0 for x in range(10)]
genr = (1 if x % 2 == 0 else 0 for x in range(10))
for v in lst:
print(v, end=" ")
print()
for v in genr:
print(v, end=" ")
print()
Son los paréntesis. Los corchetes hacen una comprensión, los paréntesis hacen un generador.
El código, cuando se ejecuta, produce dos líneas idénticas:
1 0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 1 0 1 0
¿Cómo puedes saber que la segunda asignación crea un generador, no una lista?
Hay algunas pruebas que podemos mostrarte. Aplica la función len()
a ambas entidades.
len(lst)
dará como resultado 10
, claro y predecible, len(genr)
provocará una excepción y verás el siguiente mensaje:
TypeError: object of type 'generator' has no len()
Por supuesto, guardar la lista o el generador no es necesario; puedes crearlos exactamente en el lugar donde los necesites, como aquí:
for v in [1 if x % 2 == 0 else 0 for x in range(10)]:
print(v, end=" ")
print()
for v in (1 if x % 2 == 0 else 0 for x in range(10)):
print(v, end=" ")
print()
Nota: la misma apariencia de la salida no significa que ambos bucles funcionen de la misma manera. En el primer bucle, la lista se crea (y se itera) como un todo; en realidad, existe cuando se ejecuta el bucle.
En el segundo bucle, no hay ninguna lista, solo hay valores subsequentes producidos por el generador, uno por uno.
Realiza tus propios experimentos.