Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> python

Dominando Iteradores en Python: Cómo Funcionan y Cómo Crear los Tuyos

Iteradores en Python

Descubre cómo funcionan los iteradores de Python, cómo recorrerlos con bucles for o la función next(), y cómo crear iteradores personalizados o infinitos usando el protocolo de iterador.

Video: Iteradores en Python

Iteradores en Python

Los iteradores son omnipresentes en Python. Subyacen a bucles for, list comprehensions, generadores y muchas estructuras de datos integradas, a menudo trabajando entre bastidores.

Un iterador es simplemente un objeto que produce datos un elemento a la vez. En Python, cualquier objeto que implemente los métodos __iter__() y __next__() se considera un iterador.

Cuando un objeto puede proveer un iterador, se llama iterable. La mayoría de contenedores integrados —listas, tuplas, cadenas, diccionarios— son iterables. La función integrada iter() llama al método __iter__() de un objeto para obtener un iterador.


Iterando a Través de un Iterador

Puedes avanzar manualmente un iterador con la función next(). Una vez agotado el iterador, se lanza StopIteration.

# definir una lista
my_list = [4, 7, 0, 3]
# obtener un iterador usando iter()
my_iter = iter(my_list)
# iterar a través usando next()
# Salida: 4
print(next(my_iter))
# Salida: 7
print(next(my_iter))
# next(obj) es lo mismo que obj.__next__()
# Salida: 0
print(my_iter.__next__())
# Salida: 3
print(my_iter.__next__())
# Esto lanzará error, no quedan elementos
next(my_iter)

Salida

4 7 0 3 Traceback (most recent call last): File "<string>", line 24, in <module> next(my_iter) StopIteration

Una forma más natural de iterar es usando un bucle for, que maneja automáticamente el ciclo de vida del iterador.

>>> for element in my_list:
...     print(element)
...
4
7
0
3

Cómo Funciona el Bucle for con Iteradores

El bucle for internamente se traduce a:

for element in iterable:
    # hacer algo con element

Lo cual es equivalente a la siguiente lógica:

# crear un objeto iterador desde ese iterable
iter_obj = iter(iterable)
# bucle infinito
while True:
    try:
        # obtener el siguiente elemento
        element = next(iter_obj)
        # hacer algo con element
    except StopIteration:
        # si se lanza StopIteration, salir del bucle
        break

Esto muestra que el bucle for es esencialmente un bucle infinito que confía en el protocolo de iterador y la excepción StopIteration para terminar.


Creando Iteradores Personalizados

Crear un iterador desde cero es sencillo: implementa __iter__() para devolver la instancia del iterador (a menudo self) y __next__() para producir el siguiente valor o lanzar StopIteration al terminar.

Abajo un ejemplo que produce potencias sucesivas de dos hasta un exponente máximo especificado por el usuario.

class PotDos:
    """Iterador que produce potencias de dos."""
    def __init__(self, max=0):
        self.max = max
    def __iter__(self):
        self.n = 0
        return self
    def __next__(self):
        if self.n <= self.max:
            result = 2 ** self.n
            self.n += 1
            return result
        else:
            raise StopIteration

# crear un objeto
numbers = PotDos(3)
# crear un iterable desde el objeto
i = iter(numbers)
# Usar next para obtener el siguiente elemento del iterador
print(next(i))
print(next(i))
print(next(i))
print(next(i))
print(next(i))

Salida

1 2 4 8 Traceback (most recent call last): File "/home/bsoyuj/Desktop/Untitled-1.py", line 32, in <module> print(next(i)) File "<string>", line 18, in __next__ raise StopIteration StopIteration

Usar un bucle for con el iterador personalizado es igual de simple:

>>> for i in PotDos(5):
...     print(i)
...
1
2
4
8
16
32

Iteradores Infinitos en Python

Los iteradores pueden ser ilimitados. El iter() integrado acepta un callable y un valor centinela: llama repetidamente a la función hasta que el valor devuelto iguale al centinela. Por ejemplo:

>>> int()
0
>>> inf = iter(int, 1)
>>> next(inf)
0
>>> next(inf)
0

Como int() siempre devuelve 0, iter(int, 1) nunca ve el centinela, produciendo un iterador infinito.

También puedes crear tu propio iterador infinito, como uno que produce todos los números impares:

class InfIter:
    """Iterador infinito que devuelve números impares sucesivos."""
    def __iter__(self):
        self.num = 1
        return self
    def __next__(self):
        num = self.num
        self.num += 2
        return num

Ejecución de ejemplo:

>>> a = iter(InfIter())
>>> next(a)
1
>>> next(a)
3
>>> next(a)
5
>>> next(a)
7

Al trabajar con iteradores infinitos, siempre proporciona una condición de terminación para evitar bucles infinitos.

Los iteradores son eficientes en memoria porque producen elementos bajo demanda. Puedes teóricamente generar una secuencia ilimitada —como todos los números impares— sin almacenar el conjunto completo.

Para una forma más simple de crear iteradores, explora Generadores en Python usando yield.

python

  1. Dominando tipos de datos en Python: Guía práctica
  2. Dominando operadores en Python: Guía completa
  3. Dominando la sentencia pass en Python: Guía práctica
  4. Dominando argumentos de funciones en Python: Posicionales, por palabra clave y por defecto
  5. Dominando Diccionarios en Python: Creación, Manipulación y Técnicas Avanzadas
  6. Explicación de Closures en Python: Cómo las Funciones Anidadas Capturan Variables
  7. Dominando datetime en Python: Guía Práctica de Fechas, Horas y Zonas Horarias
  8. Dominar time.sleep() en Python: Mejores Prácticas, Multihilo y Ejemplos Reales
  9. Visión general de Python: Lenguaje de alto nivel, legible, interactivo y orientado a objetos
  10. Números en Python: Entendiendo tipos de datos numéricos inmutables
  11. Dominando cadenas en Python: Creación, acceso y manipulación