14 usuarios conectados
Funciones. Generadores en Python
Funciones. Generadores en Python
Ahora vamos a explorar los generadores
en Python, una forma elegante y eficiente de crear iteradores. Los generadores
son especialmente útiles para trabajar con secuencias de datos grandes o
infinitas, ya que generan los elementos uno a la vez bajo demanda, en lugar de
almacenarlos todos en memoria de una vez.
¿Qué son los Generadores?
- Iteradores: Los generadores
son un tipo especial de función que se comporta como un iterador. Esto
significa que puedes recorrer sus elementos usando un bucle
for
o la función next().
- Lazy Evaluation: Los
generadores producen valores de forma perezosa (lazy). Solo generan el
siguiente valor cuando se les pide, lo que ahorra memoria y puede mejorar el
rendimiento para grandes conjuntos de datos.
- Uso de
yield: La
característica distintiva de un generador es el uso de la palabra clave
yield en lugar de return. Cuando una función
encuentra un yield, pausa su ejecución, guarda su estado y
devuelve el valor de la expresión yield. La próxima vez que se
solicita un valor del generador, la función se reanuda desde donde se quedó.
Definición de Funciones Generadoras:
Para crear una función generadora, simplemente
define una función normal pero utiliza la palabra clave yield una o
más veces dentro de su cuerpo.
Salida:
¿Cómo funciona?
- Cuando llamas a
mi_generador(),
no se ejecuta el código de la función inmediatamente. En cambio, se crea un
objeto generador.
- El bucle
for (o una llamada a
next() en el objeto generador) solicita el primer valor.
- La función
mi_generador() se
ejecuta hasta que encuentra la primera sentencia yield 1. El
valor 1 se devuelve y la función se pausa, guardando su estado
(incluyendo el punto de ejecución y los valores de las variables locales).
- En la siguiente iteración del bucle, se
solicita el siguiente valor. La función
mi_generador() se
reanuda desde donde se quedó y continúa hasta la siguiente sentencia
yield "dos". El valor "dos" se devuelve y la función se
pausa de nuevo.
- Este proceso se repite hasta que la función
llega al final (o encuentra una sentencia
return sin valor),
momento en el cual el generador lanza una excepción StopIteration,
indicando que no hay más valores que producir. El bucle for
maneja automáticamente esta excepción y termina.
Ejemplos de Uso de Generadores:
-
Generador para producir una secuencia
de números:
Salida:
-
Generador para leer líneas de un
archivo (eficiente para archivos grandes):
Este generador lee y devuelve cada línea del
archivo una por una, sin cargar todo el archivo en memoria.
-
Generador de números Fibonacci:
Salida:
Expresiones Generadoras:
Al igual que existen las comprensiones de
lista, también existen las expresiones generadoras, que
proporcionan una forma concisa de crear generadores anónimos utilizando una
sintaxis similar a las comprensiones de lista, pero con paréntesis ()
en lugar de corchetes [].
Salida:
Las expresiones generadoras son aún más
concisas que las funciones generadoras para casos simples.
Ventajas de los Generadores:
- Ahorro de memoria:
Generan elementos bajo demanda, por lo que no necesitan almacenar grandes
secuencias en memoria simultáneamente.
- Eficiencia: Pueden
mejorar el rendimiento al evitar la creación de listas completas cuando solo
se necesita iterar sobre los elementos una vez.
- Trabajo con secuencias infinitas:
Los generadores pueden representar secuencias infinitas, ya que solo generan
los elementos a medida que se solicitan.
- Código más limpio y legible:
Para ciertas tareas de iteración, los generadores pueden hacer que el código
sea más expresivo y fácil de entender.
Los generadores son una herramienta poderosa
en Python para el manejo eficiente de secuencias de datos, especialmente cuando
la memoria es una preocupación o cuando se trabaja con flujos de datos
continuos. ¿Te gustaría que pasemos al siguiente tema?