En Python, los iteradores son objetos que implementan el protocolo de iterador: los métodos __iter__() y __next__(). Los iteradores gestionan su estado interno y, en cada llamada a next(), devuelven el siguiente elemento de la secuencia o lanzan la excepción StopIteration al finalizar.
Los objetos iterables son aquellos sobre los que se puede iterar en un bucle (por ejemplo, listas, cadenas, diccionarios). Todos ellos tienen un método __iter__() que devuelve un iterador.
Para implementar un iterador propio, se debe crear una clase con los métodos __iter__() (que devuelve self) y __next__() (que implementa la lógica para obtener el siguiente elemento):
class Counter: def __init__(self, low, high): self.current = low self.high = high def __iter__(self): return self def __next__(self): if self.current > self.high: raise StopIteration else: self.current += 1 return self.current - 1 for num in Counter(1, 3): print(num) # 1 2 3
¿Cuál es la diferencia entre los objetos iterables y los iteradores? ¿Se puede iterar sobre un iterador más de una vez?
Respuesta: Un objeto iterable implementa solo el método __iter__(), que devuelve un iterador. Un iterador es un objeto que tiene el método __next__(). Normalmente, un iterador solo se itera una vez: después de alcanzar el final de la secuencia, la iteración repetida no es posible sin crear un nuevo iterador.
Historia
En un proyecto para el análisis de registros, un desarrollador escribió una función que recibía un iterador y trató de iterar sobre él dos veces (
for log in logs:), esperando que ambas iteraciones dieran los mismos resultados. La segunda iteración no devolvió nada porque el iterador ya estaba "agotado".
Historia
En un módulo, un desarrollador devolvió de una función no una lista, sino un generador que permitía una única iteración. Al intentar pasarlo a otra función, que esperaba un objeto iterable para múltiples recorridos, se produjo un error inesperado y un resultado vacío.
Historia
En un proyecto de API web, un desarrollador intentó serializar un iterador directamente a JSON. Los iteradores no son listas, y la conversión no es posible sin convertir primero a una lista (de lo contrario, la serialización terminará con una excepción).