Diferenciar Funciones y Generadores
En este paso, aprenderás las diferencias clave entre las funciones regulares de Python y los generadores. Comprender esta distinción es crucial para escribir código eficiente y amigable con la memoria, especialmente cuando se trabaja con conjuntos de datos grandes o secuencias infinitas.
Funciones:
Una función es un bloque de código que realiza una tarea específica. Cuando se llama a una función, ejecuta su código, potencialmente realiza cálculos y devuelve un valor (o None
si no hay una declaración return
explícita). El estado de la función no se conserva entre llamadas.
Generadores:
Un generador es un tipo especial de función que utiliza la palabra clave yield
en lugar de return
. Cuando se llama a un generador, devuelve un objeto iterador. Cada vez que solicitas un valor del iterador, el generador se ejecuta hasta que encuentra una declaración yield
. El generador luego se pausa, guarda su estado y produce el valor. La próxima vez que se solicite un valor, el generador reanuda desde donde se detuvo.
Veamos un ejemplo para ilustrar esto. Primero, crea un archivo llamado function_vs_generator.py
en tu directorio ~/project
utilizando el editor VS Code.
## ~/project/function_vs_generator.py
## Regular function
def square_numbers_function(numbers):
result = []
for number in numbers:
result.append(number * number)
return result
## Generator function
def square_numbers_generator(numbers):
for number in numbers:
yield number * number
## Example usage
numbers = [1, 2, 3, 4, 5]
## Using the function
function_result = square_numbers_function(numbers)
print("Function Result:", function_result)
## Using the generator
generator_result = square_numbers_generator(numbers)
print("Generator Result:", list(generator_result)) ## Convert generator to list for printing
Ahora, ejecuta el script de Python:
python ~/project/function_vs_generator.py
Deberías ver la siguiente salida:
Function Result: [1, 4, 9, 16, 25]
Generator Result: [1, 4, 9, 16, 25]
Tanto la función como el generador producen el mismo resultado. Sin embargo, la diferencia clave radica en cómo lo logran. La función calcula todos los cuadrados y los almacena en una lista antes de devolverlos. El generador, por otro lado, produce cada cuadrado uno a la vez, solo cuando se solicita.
Para ilustrar aún más la diferencia, modifiquemos el script para imprimir el tipo del objeto devuelto:
## ~/project/function_vs_generator.py
## Regular function
def square_numbers_function(numbers):
result = []
for number in numbers:
result.append(number * number)
return result
## Generator function
def square_numbers_generator(numbers):
for number in numbers:
yield number * number
## Example usage
numbers = [1, 2, 3, 4, 5]
## Using the function
function_result = square_numbers_function(numbers)
print("Function Result Type:", type(function_result))
## Using the generator
generator_result = square_numbers_generator(numbers)
print("Generator Result Type:", type(generator_result))
Ejecuta el script nuevamente:
python ~/project/function_vs_generator.py
La salida será:
Function Result Type: <class 'list'>
Generator Result Type: <class 'generator'>
Esto muestra claramente que la función devuelve una list
, mientras que el generador devuelve un objeto generator
. Los generadores son eficientes en memoria porque no almacenan todos los valores en memoria al mismo tiempo. Generan valores a demanda.