Estrategias de Iteración
Comprendiendo la Iteración de Generadores
La iteración de generadores puede ser compleja, con múltiples estrategias para restablecer y reutilizar generadores. A diferencia de las listas, los generadores se consumen después de una sola iteración, lo que requiere técnicas específicas para el restablecimiento.
Métodos Básicos de Iteración
Método 1: Volver a Crear el Generador
def number_generator():
yield from range(5)
## First iteration
gen1 = number_generator()
print(list(gen1)) ## [0, 1, 2, 3, 4]
## Second iteration requires recreating generator
gen2 = number_generator()
print(list(gen2)) ## [0, 1, 2, 3, 4]
import itertools
def number_generator():
yield from range(5)
## Create multiple independent iterators
gen1, gen2 = itertools.tee(number_generator())
print(list(gen1)) ## [0, 1, 2, 3, 4]
print(list(gen2)) ## [0, 1, 2, 3, 4]
Técnicas Avanzadas de Iteración
Almacenamiento en Caché de los Resultados del Generador
def cached_generator():
cache = []
def generator():
for item in range(5):
cache.append(item)
yield item
return generator, cache
gen_func, result_cache = cached_generator()
gen = gen_func()
print(list(gen)) ## [0, 1, 2, 3, 4]
print(result_cache) ## [0, 1, 2, 3, 4]
Comparación de Estrategias de Iteración
| Estrategia |
Eficiencia en Memoria |
Complejidad |
Reutilización |
| Volver a Crear el Generador |
Alta |
Baja |
Moderada |
| itertools.tee() |
Moderada |
Media |
Alta |
| Almacenamiento en Caché |
Baja |
Alta |
Alta |
Flujo de Iteración de Generadores
graph LR
A[Generator Creation] --> B{Iteration Started}
B --> |First Pass| C[Values Consumed]
C --> |Reset Needed| D[Recreate Generator]
D --> B
Mejores Prácticas
- Prefiere la recreación para generadores simples.
- Utiliza
itertools.tee() para iteraciones en paralelo.
- Implementa un almacenamiento en caché personalizado para escenarios complejos.
Consideraciones de Rendimiento
En LabEx, recomendamos elegir estrategias de iteración basadas en:
- Restricciones de memoria
- Complejidad computacional
- Requisitos específicos del caso de uso
Manejo de Errores en Iteraciones
def safe_generator():
try:
yield from range(5)
except GeneratorExit:
print("Generator closed")
gen = safe_generator()
list(gen) ## Normal iteration
gen.close() ## Explicit closure
Técnica Avanzada: Envoltorio de Generador
def generator_wrapper(gen_func):
def wrapper(*args, **kwargs):
return gen_func(*args, **kwargs)
return wrapper
@generator_wrapper
def repeatable_generator():
yield from range(3)