ProgramaciónDesarrollador de Python

Explique qué son los generadores en Python. ¿Cómo funcionan, para qué se utilizan y en qué se diferencian de las expresiones generadoras?

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

Los generadores son objetos iterables especiales en Python que permiten crear secuencias "sobre la marcha", sin ocupar memoria para toda la colección de una vez. Se implementan mediante funciones con la palabra clave yield o expresiones generadoras ((expr for ... in ...)). Esto es conveniente cuando se trabaja con grandes volúmenes de datos o flujos potencialmente infinitos.

Diferencias clave con las expresiones generadoras:

  • Expresiones generadoras ([x for x in range(10)]) crean toda la lista en memoria de inmediato.
  • Generadores ((x for x in range(10))) crean elementos uno por uno, consumiendo mucha menos memoria.

Cuándo usar generadores:

  • Si no se necesita acceso a los elementos por índice.
  • Si los datos son demasiado grandes para almacenarlos en memoria.
  • Al organizar el procesamiento de datos en flujo (por ejemplo, leer líneas de un archivo).
# Función generadora def contador(n): for i in range(n): yield i for numero in contador(5): print(numero)

Pregunta capciosa.

"¿Cuál es la diferencia entre usar una función con yield y una función normal que devuelve una lista? Proporcione un ejemplo."

Respuesta: Una función normal calcula y devuelve la lista de inmediato, ocupando memoria para todos sus elementos. Una función con yield devuelve un generador, que produce elementos uno por uno y no carga toda la secuencia en memoria de inmediato.

def hacer_lista(n): return [i for i in range(n)] # Devuelve la lista de inmediato, ocupa mucha memoria def hacer_generador(n): for i in range(n): yield i # Producirá un elemento a la vez

Ejemplos de errores reales por desconocer los matices del tema.


Historia

En un proyecto para analizar grandes registros se utilizaron expresiones generadoras para extraer líneas que contenían errores:

lineas_error = [linea for linea in open('biglog.txt') if 'ERROR' in linea]

El archivo superaba los 2 GB y la aplicación falló con OOM (Fuera de Memoria). Se necesitaba usar un generador:

lineas_error = (linea for linea in open('biglog.txt') if 'ERROR' in linea)

Historia

Un empleado quería analizar una lista corta, escribió una función con yield, pero olvidó que se devuelve un generador, no una lista:

resultado = mi_funcion_generadora() # resultado es un generador, no una lista if len(resultado) > 5: # TypeError: object of type 'generator' has no len()

Corrección: envolver el resultado en list().


Historia

Se intentó iterar sobre el generador varias veces:

numeros = (i for i in range(5)) for n in numeros: pass # se agotó el generador for n in numeros: print(n) # no imprime nada

El generador es de un solo uso. Se necesita crear uno nuevo para reutilizarlo.