El bucle for x in y de Python parece una construcción trivial: recorres una lista, una cadena o un rango y obtienes un elemento cada vez. Sin embargo, bajo esa sintaxis amable se esconde un mecanismo bien definido que conviene entender para depurar generadores, iterables personalizados o errores con iteradores agotados. La clave es que Python no itera directamente sobre la colección, sino sobre un iterador. Cuando el intérprete encuentra for x in y, en realidad realiza tres pasos: llama a iter(y) para obtener un iterador, invoca next(...) de forma repetida para obtener cada valor, y detiene el bucle cuando next(...) lanza la excepción StopIteration. Esta cadena se puede reproducir a mano desde cualquier REPL y demuestra que for no es un caso especial para listas o cadenas, sino un envoltorio sobre el protocolo de iteración. Esa idea explica por qué listas, tuplas, cadenas, rangos y generadores funcionan de forma idéntica con for: cada uno sabe producir su propio iterador, y el bucle no necesita lógica específica para cada tipo. También aclara matices prácticos, como que un iterable (por ejemplo, una lista) suele entregar un iterador nuevo en cada pasada, mientras que un iterador (como un generador) es de un solo uso; una vez agotado, un segundo for sobre él no produce nada. Un caso especialmente potente es for x, y in z: no se trata de una variante distinta de bucle, sino de iteración ordinaria seguida de desempaquetado de tuplas. En objetos personalizados, basta con implementar __iter__ y __next__ para integrarse en el mismo protocolo. Comprender este andamiaje convierte for en una pieza transparente del lenguaje en lugar de una caja opaca.
Lo que `for x in y` esconde de ti en Python
Fuentes:
What `for x in y` hides from you
