Introducción
Los generadores en Python son una forma especial de iteradores que permiten crear secuencias de valores de manera eficiente y perezosa (lazy evaluation). A diferencia de las funciones normales que devuelven un valor y terminan su ejecución, los generadores pueden pausar su ejecución y reanudarla más tarde, lo que los hace ideales para trabajar con grandes conjuntos de datos o flujos de datos continuos.
Conceptos Clave
- Iterador: Un objeto que implementa los métodos
__iter__()
y__next__()
, permitiendo iterar sobre sus elementos uno a uno. - Generador: Un tipo especial de iterador que se define utilizando una función con la palabra clave
yield
en lugar dereturn
. - Lazy Evaluation: Evaluación diferida de una expresión hasta que su valor sea necesario, lo que permite ahorrar memoria y mejorar el rendimiento.
Creación de Generadores
Usando Funciones con yield
La forma más común de crear un generador es mediante una función que utiliza la palabra clave yield
para devolver valores uno a uno.
def contador(maximo): contador = 0 while contador < maximo: yield contador contador += 1 # Uso del generador for numero in contador(5): print(numero)
Explicación:
- La función
contador
es un generador porque utilizayield
. - Cada vez que se llama a
yield
, la ejecución de la función se pausa y se devuelve el valor actual decontador
. - La próxima vez que se itera sobre el generador, la ejecución se reanuda justo después de la última llamada a
yield
.
Usando Expresiones Generadoras
Las expresiones generadoras son similares a las comprensiones de listas, pero en lugar de crear una lista en memoria, crean un generador.
# Expresión generadora generador = (x * x for x in range(5)) # Uso del generador for valor in generador: print(valor)
Explicación:
- La expresión
(x * x for x in range(5))
crea un generador que calcula los cuadrados de los números del 0 al 4. - Al iterar sobre el generador, se calculan y devuelven los valores uno a uno.
Ejemplos Prácticos
Generador de Números Fibonacci
def fibonacci(n): a, b = 0, 1 for _ in range(n): yield a a, b = b, a + b # Uso del generador for numero in fibonacci(10): print(numero)
Explicación:
- La función
fibonacci
genera los primerosn
números de la secuencia de Fibonacci. - Cada llamada a
yield
devuelve el valor actual dea
y luego actualizaa
yb
.
Generador Infinito
def contador_infinito(): contador = 0 while True: yield contador contador += 1 # Uso del generador for numero in contador_infinito(): if numero > 10: break print(numero)
Explicación:
- La función
contador_infinito
genera un contador infinito. - El bucle
while True
asegura que el generador nunca se detenga a menos que se rompa explícitamente.
Ejercicios Prácticos
Ejercicio 1: Generador de Números Pares
Instrucciones:
Crea un generador que devuelva los primeros n
números pares.
def numeros_pares(n): for i in range(n): yield i * 2 # Uso del generador for numero in numeros_pares(5): print(numero)
Solución:
def numeros_pares(n): for i in range(n): yield i * 2 # Uso del generador for numero in numeros_pares(5): print(numero)
Ejercicio 2: Generador de Números Primos
Instrucciones:
Crea un generador que devuelva los primeros n
números primos.
def es_primo(num): if num < 2: return False for i in range(2, int(num ** 0.5) + 1): if num % i == 0: return False return True def numeros_primos(n): contador, num = 0, 2 while contador < n: if es_primo(num): yield num contador += 1 num += 1 # Uso del generador for primo in numeros_primos(5): print(primo)
Solución:
def es_primo(num): if num < 2: return False for i in range(2, int(num ** 0.5) + 1): if num % i == 0: return False return True def numeros_primos(n): contador, num = 0, 2 while contador < n: if es_primo(num): yield num contador += 1 num += 1 # Uso del generador for primo in numeros_primos(5): print(primo)
Conclusión
Los generadores son una herramienta poderosa en Python para manejar secuencias de datos de manera eficiente y con un uso mínimo de memoria. Al utilizar yield
, puedes crear iteradores personalizados que pueden pausar y reanudar su ejecución, lo que es especialmente útil para trabajar con grandes conjuntos de datos o flujos de datos continuos. Con la práctica, los generadores pueden convertirse en una parte esencial de tu caja de herramientas de programación en Python.
Curso de Programación en Python
Módulo 1: Introducción a Python
- Introducción a Python
- Configuración del Entorno de Desarrollo
- Sintaxis de Python y Tipos de Datos Básicos
- Variables y Constantes
- Entrada y Salida Básica
Módulo 2: Estructuras de Control
- Sentencias Condicionales
- Bucles: for y while
- Herramientas de Control de Flujo
- Comprensiones de Listas
Módulo 3: Funciones y Módulos
- Definición de Funciones
- Argumentos de Función
- Funciones Lambda
- Módulos y Paquetes
- Visión General de la Biblioteca Estándar
Módulo 4: Estructuras de Datos
Módulo 5: Programación Orientada a Objetos
Módulo 6: Manejo de Archivos
- Lectura y Escritura de Archivos
- Trabajo con Archivos CSV
- Manejo de Datos JSON
- Operaciones de Archivos y Directorios
Módulo 7: Manejo de Errores y Excepciones
- Introducción a las Excepciones
- Manejo de Excepciones
- Lanzamiento de Excepciones
- Excepciones Personalizadas
Módulo 8: Temas Avanzados
- Decoradores
- Generadores
- Administradores de Contexto
- Concurrencia: Hilos y Procesos
- Asyncio para Programación Asíncrona
Módulo 9: Pruebas y Depuración
- Introducción a las Pruebas
- Pruebas Unitarias con unittest
- Desarrollo Guiado por Pruebas
- Técnicas de Depuración
- Uso de pdb para Depuración
Módulo 10: Desarrollo Web con Python
- Introducción al Desarrollo Web
- Fundamentos del Framework Flask
- Construcción de APIs REST con Flask
- Introducción a Django
- Construcción de Aplicaciones Web con Django
Módulo 11: Ciencia de Datos con Python
- Introducción a la Ciencia de Datos
- NumPy para Computación Numérica
- Pandas para Manipulación de Datos
- Matplotlib para Visualización de Datos
- Introducción al Aprendizaje Automático con scikit-learn