Introducción a los iteradores de Python

Un iterador en Python se refiere a un objeto sobre el que podemos iterar. El iterador consta de valores contables, y es posible atravesar estos valores...

¿Qué son los iteradores?

Un iterador en Python se refiere a un objeto sobre el que podemos iterar. El iterador consta de valores contables y es posible atravesar estos valores, uno por uno.

El iterador simplemente implementa el protocolo iterador de Python. El protocolo iterador es una clase de Python que viene con dos métodos especiales, a saber, __iter__() y __next__(). Con estos dos métodos, el iterador puede calcular el siguiente valor de la iteración.

Con los iteradores, es fácil para nosotros trabajar con secuencias de elementos en Python. No tenemos que asignar recursos informáticos a todos los elementos de la secuencia, sino que iteramos sobre un solo elemento a la vez, lo que nos ayuda a ahorrar espacio en la memoria.

En este artículo, estudiaremos cómo trabajar con iteradores en Python.

Objetos iterables en Python

Un iterable es un objeto capaz de devolver un iterador. Un iterable puede representar fuentes de datos tanto finitas como infinitas. El iterable implementa directa o indirectamente los dos métodos: __iter__() y __next__(). El método __iter__() devuelve el objeto iterador mientras que el método __next__() nos ayuda a recorrer los elementos en el objeto iterable.

Los ejemplos de objetos iterables en Python incluyen listas, diccionarios, tuplas y conjuntos.

Creación de un iterador

En Python, creamos un iterador implementando los métodos __iter__() y __next__() en el objeto. Considere el siguiente ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
class IterationExample:
    def __iter__(self):
        self.x = 0
        return self

    def __next__(self):
        y = self.x
        self.x += 1
        return y

classinstance = IterationExample()
element = iter(classinstance)

Hemos creado un iterador llamado element que imprime números del 0 al N. Primero creamos una instancia de la clase y le dimos el nombre classinstance. Luego llamamos al método integrado iter() y pasamos el nombre de la instancia de la clase como parámetro. Esto crea el objeto iterador.

Analicemos ahora cómo usar un iterador para iterar realmente a través de los elementos.

Iterando a través de un iterador

El método next() nos ayuda a iterar a través de los elementos de un iterador. Demostremos esto con el ejemplo anterior:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class IterationExample:
    def __iter__(self):
        self.x = 0
        return self

    def __next__(self):
        y = self.x
        self.x += 1
        return y

classinstance = IterationExample()
element = iter(classinstance)

print(next(element))
print(next(element))
print(next(element))
print(next(element))
print(next(element))
print(next(element))
print(next(element))
print(next(element))
print(next(element))
print(next(element))

Producción

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
0
1
2
3
4
5
6
7
8
9

En el script anterior, llamamos al método next() y pasamos el nombre del elemento iterador al método como parámetro. Cada vez que hacemos esto, el iterador se mueve al siguiente elemento de la secuencia. Aquí hay otro ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# create a list
list1 = [0, 5, 10, 15]

# create an iterator
element = iter(list1)

## use next() to traverse/iterate through the list elements

# prints first element, 0
print(next(element))

# prints second element, 5
print(next(element))

## next(element) is similar to element.__next__()

# prints third element, 10
print(element.__next__())

# prints fourth element, 15
print(element.__next__())

Producción

1
2
3
4
0
5
10
15

En el script anterior, creamos una lista llamada list1, que tiene 4 enteros. Se ha creado un iterador denominado element. El método next() nos ha ayudado a iterar a través de los elementos de la lista.

Iteración con el bucle "for"

El bucle for nos ayuda a iterar a través de cualquier objeto capaz de devolver un iterador. Por ejemplo:

1
2
3
4
5
6
7
8
9
# create a list
list1 = [0, 5, 10, 15]

# create an iterator
element = iter(list1)

# iterate with a for loop
for x in element:
    print(x)

Producción

1
2
3
4
0
5
10
15

En el código anterior, creamos una variable llamada x, que se usa para iterar a través del iterador element a través de un bucle for.

Iteradores infinitos

Un iterador infinito es un iterador con un número infinito de iteraciones. Debemos tener mucho cuidado cuando se trata de iteradores infinitos. Considere el siguiente ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class IterationExample:
    def __iter__(self):
        self.x = 0
        return self

    def __next__(self):
        y = self.x
        self.x += 1
        return y

classinstance = IterationExample()
element = iter(classinstance)

for x in element:
    print(x)

El código anterior se ejecutará para siempre. Para detenerlo, deberá intervenir manualmente. Aquí hay otro ejemplo que demuestra cómo crear un iterador infinito en Python:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Infinite:
    # Print all even numbers

    def __iter__(self):
        self.x = 0
        return self

    def __next__(self):
        x = self.x
        self.x += 2
        return x

El código debe devolver todos los números pares, comenzando desde 0. Podemos ejecutar el código como se muestra a continuación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
>>> y = iter(Infinite())
>>> next(y)
0
>>> next(y)
2
>>> next(y)
4
>>> next(y)
6
>>> next(y)
8
>>> next(y)
10
>>>

Y la cadena anterior puede continuar para siempre. Esto muestra que con un iterador infinito, podemos tener un número infinito de elementos sin tener que almacenarlos todos en la memoria.

En la siguiente sección, veremos cómo podemos implementar un mecanismo para salir de esos infinitos iteradores.

Detener una iteración

En la sección anterior, vimos cómo crear un iterador infinito en Python. Sin embargo, los iteradores no suelen estar destinados a iteraciones infinitas en Python. Siempre es conveniente implementar una condición de terminación.

Podemos evitar que un iterador se ejecute para siempre usando la instrucción StopIteration. Solo necesitamos agregar una condición de terminación en el método __next__() que generará un error una vez que se haya alcanzado el número especificado de iteraciones. Aquí hay un ejemplo:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class StoppingIteration:
    def __iter__(self):
        self.x = 1
        return self

    def __next__(self):
        if self.x <= 5:
            y = self.x
            self.x += 1
            return y
        else:
            raise StopIteration

classinstance = StoppingIteration()
element = iter(classinstance)

for a in element:
    print(a)

Producción

1
2
3
4
5
1
2
3
4
5

La ejecución se detiene después de 5 iteraciones. Esto se debe a la condición self.x <= 5: agregada dentro del método __next__(). Si se llama al iterador después de llegar a 5, generará el evento StopIteration. Considere el ejemplo dado a continuación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class StoppingIteration:
    def __init__(self, max = 0):
        self.max = max

    def __iter__(self):
        self.x = 1
        return self

    def __next__(self):
        if self.x <= self.max:
            val = 3 ** self.x
            self.x += 1
            return val
        else:
            raise StopIteration

Vamos a crear un iterador y luego iterar a través de él:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
>>> y = StoppingIteration(3)
>>> z = iter(y)
>>> next(z)
3
>>> next(z)
9
>>> next(z)
27
>>> next(z)
Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    next(z)
  File "C:\Users\admin\iteration.py", line 17, in __next__
    raise StopIteration
StopIteration
>>>

La condición de terminación se ha implementado en la siguiente sección de nuestro código:

1
2
if self.x <= self.max:
    val = 3 ** self.x

Pasamos un valor de 3 al iterador, lo que significa que el iterador no debe iterar más allá de 27, es decir, 3^3.

Conclusión

Los iteradores son extremadamente útiles, especialmente si necesita iterar a través de una gran secuencia de elementos. Los iteradores le permiten iterar a través de una secuencia de elementos de uno en uno sin tener que cargar todos los elementos en la memoria a la vez.

En este artículo, vimos cómo crear iteradores en Python y cómo iterar a través de elementos en un iterador. También vimos cómo crear un iterador infinito y cómo agregar una condición de terminación a un iterador infinito. nito.

Licensed under CC BY-NC-SA 4.0