¿Debería preferir los generadores Python a las listas?

8

Los iteradores de Python pueden ser muy eficientes en memoria. ¿Debería preferir siempre usar generadores en lugar de solo listas? ¿En qué situaciones debería preferir una matriz simple?

Por ejemplo en lugar de esto:

emails = [user.email for user in users]

debería preferir esto ?:

emails = (user.email for user in users)

Nota : quiero decir 'generadores' no 'iteradores'.

Nicholaides
fuente
No está claro qué ayuda necesita . Aclare su problema específico o proporcione detalles adicionales para resaltar exactamente lo que necesita. Como está escrito actualmente, es difícil saber qué problema está tratando de resolver o qué aspecto de su enfoque debe corregirse o explicarse. Consulte lapágina Cómo preguntar para obtener ayuda para aclarar esta pregunta.
mosquito
@gnat, la pregunta se reformularía como "¿cuándo debo usar iteradores o listas en Python?" ¿estar bien?
Florian Margaine
@FlorianMargaine que lo pondría en riesgo de ser cerrado como demasiado amplio , me temo
mosquito
2
@FlorianMargaine Ese sería un buen comienzo, pero sigue siendo una pregunta débil. ¿Dónde está la investigación del autor? Seguramente puede pensar en algunas diferencias. Pedir enumerar todas las situaciones en las que es posible que desee utilizar una u otra no es tan bueno.
Doval
2
+1 Puede ser una pregunta un poco confusa, pero cuando estás aprendiendo a usar estas estructuras, tus preguntas se formarán y redactarán vagamente. Aprendí mucho de las respuestas.
Racheet

Respuestas:

7

El principal inconveniente de los generadores es que solo pueden atravesarse en una dirección. No hay vuelta atrás a un valor anterior. Tampoco puedes compartirlos. Hay muchos casos en los que eso puede explicarse fácilmente, o incluso donde es preferible, pero también hay muchos casos en los que no lo es. Clasificación, por ejemplo.

Es por eso que muchas veces verá generadores utilizados para las etapas iniciales de procesamiento de una gran cantidad de datos, luego, una vez que se filtra en un subconjunto y se mapea en un formato agradable, se coloca en una estructura de datos concreta de larga duración para uso posterior. De esta forma, no gasta la asignación de memoria, errores de caché y costos de recolección de basura para matrices intermedias grandes que tirará inmediatamente.

Karl Bielefeldt
fuente
3

Tienes iteradores confundidos con generadores.

Su primer ejemplo es una expresión de iterador de lista, mientras que el segundo es una expresión generadora. La diferencia clave es que el generador crea cada miembro de la colección dada de forma perezosa (según sea necesario) en lugar de con entusiasmo (a la vez, sea necesario o no). Puede definir sus propios generadores utilizando el rendimiento en lugar del retorno.

En cuanto al uso, desea un iterador cuando necesita la lista (o diccionario o lo que sea) para algo en sí mismo. Usaría un generador cuando la colección sea incidental al producto final. Por ejemplo, puede usar un generador para obtener una lista de números que satisfacen algunos criterios de otros criterios. No le importa la lista original, solo los miembros que cumplen con los criterios. Por lo tanto, utiliza un generador para obtener solo esos números.

Un ejemplo más concreto sería encontrar los ángulos de triángulos cuyos lados tienen una longitud dada. No queremos todos los triángulos fallidos pobres y deformados, solo los triángulos exitosos fuertes y saludables. Por lo tanto, usaríamos un generador.

Esta publicación de desbordamiento de pila entra en más detalles.

Ingeniero mundial
fuente