Diferenciar iterador y generador en Python
Los iteradores y generadores nos ayudan a generar algún resultado o procesar algún código iterativamente, un bit a la vez. En este artículo, aprenderemos algunas diferencias básicas entre los iteradores y generadores de Python con un ejemplo simple.
Iterador en Python
Las características básicas de un iterador son las siguientes:
- Un iterador es un objeto creado usando una clase que implementa el protocolo del iterador. Esto significa que la clase tiene definidos los métodos
__iter__
y__next__
. - El método
__next__
utiliza la instrucciónreturn
para devolver un valor. Dado que la instrucciónreturn
debe ser la última línea de ese método, debemos actualizar la variable que se usará en la próxima ejecución de__next__
antes de la declaraciónreturn
.
En el caso más simple, veremos, __iter__
devuelve self
.
Generador en Python
Las características básicas de un generador son las siguientes:
- Un generador es una función.
- Una función generadora utiliza la palabra clave
yield
en lugar de la palabra clavereturn
.
2.1 La palabra claveyield
arroja un valor y suspende la ejecución de la función.
2.2 La siguiente llamada anext()
reanuda la ejecución del código después de la instrucciónyield
.
Una función de generador nos permite crear un iterador de generador sin todo el código adicional requerido al crear un iterador usando una clase.
Ejemplos de iterador y generador en Python
Los siguientes dos ejemplos resaltan los puntos mencionados en las dos secciones anteriores. Ambos ejemplos ilustran cómo generar cuadrados de números enteros, comenzando con 1.
El primer ejemplo muestra cómo se hace usando un iterador. El segundo ejemplo muestra un código equivalente utilizando un generador.
Código de ejemplo para iterador:
# ITERATOR (Class)
class squares(object):
def __init__(self, num1):
self.nxt_sq_of = 1
self.lim = num1
def __iter__(self):
return self
def __next__(self):
if self.nxt_sq_of <= self.lim:
ret_sq_of = self.nxt_sq_of
self.nxt_sq_of += 1
return ret_sq_of * ret_sq_of
else:
raise StopIteration
# Iterator Object
a = squares(6)
# Next value of the iterator.
next(a)
next(a)
next(a)
next(a)
next(a)
next(a)
next(a)
next(a)
# Using the iterator in a loop.
a1 = squares(6)
while True:
print(next(a1))
Producción :
next(a)
Out[3]: 1
next(a)
Out[4]: 4
next(a)
Out[5]: 9
next(a)
Out[6]: 16
next(a)
Out[7]: 25
next(a)
Out[8]: 36
next(a)
Traceback (most recent call last):
File "<ipython-input-9-15841f3f11d4>", line 1, in <module>
next(a)
File "<ipython-input-1-9dbe8e565876>", line 17, in __next__
raise StopIteration
StopIteration
Código de ejemplo para generador:
# GENERATOR FUNCTION
def gen_squares(num2):
i = 1
while i <= num2:
yield i * i
i += 1
# Generator iterator.
b = gen_squares(5)
# Next yield of the generator iterator.
next(b)
next(b)
next(b)
next(b)
next(b)
next(b)
Producción :
next(b)
Out[3]: 1
next(b)
Out[4]: 4
next(b)
Out[5]: 9
next(b)
Out[6]: 16
next(b)
Out[7]: 25
next(b)
Traceback (most recent call last):
File "<ipython-input-8-adb3e17b0219>", line 1, in <module>
next(b)
StopIteration
Conclusión
Encontramos que los generadores de Python nos permiten escribir código conciso para crear un iterador de generador.
Los iteradores, por otro lado, son mucho más poderosos porque le permiten al programador escribir código personalizado para el método __iter__
.
Para obtener más detalles, consulte lo siguiente.
- Artículo Wiki de Python para generadores.
- Artículo Wiki de Python para iteradores.