Iteradores y el Protocolo de Iterador
La iteración está en todas partes en Python: bucles for, comprensiones, desempaquetado y sum. Los objetos participan implementando el protocolo de iterador o delegando a generadores.
Busca en todas las páginas de la documentación
La iteración está en todas partes en Python: bucles for, comprensiones, desempaquetado y sum. Los objetos participan implementando el protocolo de iterador o delegando a generadores.
class Countdown:
def __init__(self, start: int) -> None:
self.current = start
def __iter__(self):
return self
def __next__(self) -> int:
if self.current < 0:
raise StopIteration
value = self.current
self.current -= 1
return value
for n in Countdown(3):
print(n)Cuándo usar esto:
itertools y bucles forfrom collections.abc import Iterable, Iterator
class CSVLines:
def __init__(self, lines: Iterable[str]) -> None:
self._lines = iter(lines)
def __iter__(self) -> Iterator[list[str]]:
for raw in self._lines:
yield [cell.strip() for cell in raw.split(",")]
def take(iterator: Iterator[int], n: int) -> list[int]:
result: list[int] = []
for _ in range(n):
try:
result.append(next(iterator))
except StopIteration:
break
return result
if __name__ == "__main__":
rows = CSVLines(["a,b", "c,d"])
for row in rows:
print(row)
print(take(iter(range(10)), 3))Lo que esto demuestra:
__iter__ (el generador es un iterador)iter() obtiene un iterador; next() extrae elementos hasta StopIterationtake consume manualmente un iterador con lectura limitada__iter__ devolviendo un iterador.__iter__ (devuelve self) y __next__.for.yield crea un iterador automáticamente.| Objeto | Métodos requeridos |
|---|---|
| Iterable | __iter__ |
| Iterator | __iter__, __next__ |
# iter con sentinel para fragmentos binarios
with open("data.bin", "rb") as fh:
for chunk in iter(lambda: fh.read(4096), b""):
process(chunk)for. Solución: Llamar a iter() de nuevo solo en iterables.return simple; en __next__ lanzar StopIteration.__iter__.take/islice.| Alternativa | Usar cuando | No usar cuando |
|---|---|---|
| Función generadora | La mayoría de iteraciones personalizadas | Se necesita estado de clase más allá de yield |
itertools | Álgebra de iteradores estándar | Bucle simple único |
Materializar en list | Necesidad de reutilización/acceso aleatorio | Streams demasiado grandes |
| Iterador asíncrono | async for con I/O | Pipeline solo síncrono |
Un iterable produce iteradores. Un iterador produce elementos una vez hasta que se agota.
Señala el fin de la iteración al mecanismo del bucle for; no está destinado al control de flujo general en el código de la aplicación.
Solo si el objeto es iterable y devuelve un nuevo iterador en cada llamada a iter(). Los generadores se agotan después de un solo paso.
it = iter(obj); while True: try: x = next(it) ... except StopIteration: break
Llama repetidamente a la función hasta que se alcanza el sentinel; útil para leer streams.
Comprobación estructural de isinstance; las clases personalizadas pueden registrarse o implementar __iter__.
Los generadores son más rápidos de escribir; las clases se usan cuando se necesita estado complejo o múltiples métodos.
Las funciones integradas devuelven iteradores; se consumen una vez, eficientes en memoria.
__aiter__/__anext__ con async for; ver la sección de asyncio.
list(iterator) para materializar lo esperado; afirmar StopIteration en llamadas next adicionales.
Versiones de la pila: Esta página fue escrita para Python 3.14.0 (estable 3.14, mantenimiento 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, y uv 0.6+.
Revisado por Chris St. John·Última actualización: 19 jul 2026