Python3 Iteradores y Generadores
Iteradores
La iteración es una de las funciones más potentes de Python y es una forma de acceder a los elementos de una colección.
Un iterador es un objeto que puede recordar la posición de un recorrido.
El objeto iterador comienza a acceder desde el primer elemento de la colección y termina cuando se han visitado todos los elementos. El iterador solo puede avanzar, no retroceder.
El iterador tiene dos métodos básicos:iter()ynext()。
Los objetos de tipo cadena, lista o tupla se pueden usar para crear iteradores:
Ejemplo (Python 3.0+)
>>> it = iter(list) # Crear el objeto iterador
>>> print (next(it)) # Imprimir el siguiente elemento del iterador
1
>>> print (next(it))
2
>>>
Los objetos iteradores se pueden recorrer usando la sentencia for habitual:
Ejemplo (Python 3.0+)
Al ejecutar el programa anterior, el resultado es el siguiente:
1 2 3 4
También se puede usar la función next():
Ejemplo (Python 3.0+)
Al ejecutar el programa anterior, el resultado es el siguiente:
1 2 3 4
Crear un iterador
Para usar una clase como iterador, es necesario implementar dos métodos en la clase: __iter__() y __next__().
Si ya conoces la programación orientada a objetos, sabrás que una clase tiene un constructor; el constructor de Python es __init__(), que se ejecuta cuando el objeto se inicializa.
Para más información, consulta:Python3 Programación Orientada a Objetos
El método __iter__() devuelve un objeto iterador especial. Este objeto iterador implementa el método __next__() y señala la finalización de la iteración mediante la excepción StopIteration.
El método __next__() (en Python 2 es next()) devuelve el siguiente objeto del iterador.
Crea un iterador que devuelve números, con valor inicial 1 e incremento de 1 en 1:
Ejemplo (Python 3.0+)
El resultado de la ejecución es:
1 2 3 4 5
StopIteration
La excepción StopIteration se usa para indicar la finalización de la iteración, evitando así bucles infinitos. En el método __next__() podemos configurar que, después de completar un número determinado de iteraciones, se lance la excepción StopIteration para terminar la iteración.
Detener la ejecución después de 20 iteraciones:
Ejemplo (Python 3.0+)
El resultado de la ejecución es:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
Generadores
En Python, las funciones que utilizanyieldse denominan generadores (generator).
yieldes una palabra clave utilizada para definir funciones generadoras. Una función generadora es un tipo especial de función que puede producir valores gradualmente durante la iteración, en lugar de devolver todos los resultados de una sola vez.
A diferencia de las funciones normales, un generador es una función que devuelve un iterador y solo se puede usar para operaciones de iteración. Para entenderlo más fácilmente, un generador es un iterador.
Cuando se usa la sentenciayielden una función generadora, la ejecución de la función se pausa y el valor de la expresión que sigue ayieldse devuelve como valor de la iteración actual.
Luego, cada vez que se llama al métodonext()o se usa el bucleforpara iterar, la función continúa desde donde se pausó la última vez, hasta que de nuevo se encuentra con la sentenciayieldDe esta manera, la función generadora puede producir valores paso a paso sin necesidad de calcular y devolver todos los resultados de una sola vez.
Al llamar a una función generadora, se devuelve un objeto iterador.
A continuación se muestra un ejemplo sencillo que demuestra el uso de funciones generadoras:
Ejemplo
En el ejemplo anterior, la funcióncountdownes una función generadora. Utiliza la sentencia yield para producir gradualmente los números descendentes de n a 1. Cada vez que se ejecuta la sentencia yield, la función devuelve el valor descendente actual y, en la siguiente llamada, continúa desde donde se pausó.
Al crear un objeto generador y usar la función next() o un bucle for para iterar el generador, podemos obtener gradualmente los valores producidos por la función generadora. En este ejemplo, primero usamos la función next() para obtener los primeros tres valores descendentes y luego usamos un bucle for para obtener los dos restantes.
La ventaja de las funciones generadoras es que pueden generar valores bajo demanda, evitando generar grandes cantidades de datos de una sola vez y ocupar mucha memoria. Además, los generadores pueden combinarse sin problemas con otras herramientas de iteración (como el bucle for), proporcionando una forma de iteración simple y eficiente.
Al ejecutar el programa anterior, el resultado es el siguiente:
5 4 3 2 1
El siguiente ejemplo utiliza yield para implementar la secuencia de Fibonacci:
Ejemplo (Python 3.0+)
Al ejecutar el programa anterior, el resultado es el siguiente:
0 1 1 2 3 5 8 13 21 34 55Otras extensiones