Saltar al contenido

¿Qué son exactamente iterador, iterable e iteración?

No busques más por todo internet ya que estás al espacio correcto, tenemos la solución que necesitas recibir y sin problemas.

Solución:

Iteración es un término general para tomar cada elemento de algo, uno tras otro. Cada vez que usa un bucle, explícito o implícito, para repasar un grupo de elementos, eso es iteración.

En Python, iterable y iterador tienen significados específicos.

Un iterable es un objeto que tiene un __iter__ método que devuelve un iterador, o que define un __getitem__ método que puede tomar índices secuenciales a partir de cero (y genera un IndexError cuando los índices ya no son válidos). Entonces un iterable es un objeto que puede obtener un iterador desde.

Un iterador es un objeto con un next (Python 2) o __next__ (Python 3) método.

Siempre que use un for bucle, o map, o una lista de comprensión, etc. en Python, el next se llama automáticamente al método para obtener cada elemento del iterador, pasando así por el proceso de iteración.

Un buen lugar para comenzar a aprender sería la sección de iteradores del tutorial y la sección de tipos de iteradores de la página de tipos estándar. Una vez que comprenda los conceptos básicos, pruebe la sección de iteradores del CÓMO de programación funcional.

Aquí está la explicación que utilizo al enseñar clases de Python:

Un ITERABLE es:

  • cualquier cosa sobre la que se pueda realizar un bucle (es decir, se puede realizar un bucle string o archivo) o
  • cualquier cosa que pueda aparecer en el lado derecho de un bucle for: for x in iterable: ... o
  • cualquier cosa con la que puedas llamar iter() que devolverá un ITERADOR: iter(obj) o
  • un objeto que define __iter__ que devuelve un ITERATOR nuevo, o puede tener un __getitem__ método adecuado para búsquedas indexadas.

Un ITERADOR es un objeto:

  • con estado que recuerda dónde está durante la iteración,
  • con un __next__ método que:
    • devuelve el siguiente valor en la iteración
    • actualiza el estado para apuntar al siguiente valor
    • señala cuando se hace levantando StopIteration
  • y eso es auto-iterable (lo que significa que tiene un __iter__ método que regresa self).

Notas:

  • El __next__ el método en Python 3 está escrito next en Python 2, y
  • La función incorporada next() llama a ese método en el objeto que se le ha pasado.

Por ejemplo:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable

Las respuestas anteriores son geniales, pero como la mayor parte de lo que he visto, no enfatice el distinción suficiente para gente como yo.

Además, la gente tiende a volverse “demasiado pitónica” al poner definiciones como “X es un objeto que tiene __foo__() método “antes. Tales definiciones son correctas – se basan en la filosofía de tipificación de patos, pero el enfoque en los métodos tiende a interponerse cuando se trata de entender el concepto en su simplicidad.

Entonces agrego mi versión.


En lenguaje natural,

  • iteración es el proceso de tomar un elemento a la vez en una fila de elementos.

En Python,

  • iterable es un objeto que es, bueno, iterable, lo que en pocas palabras, significa que se puede usar en iteración, por ejemplo, con un for círculo. ¿Cómo? Mediante el uso iterador. Te lo explicaré a continuación.

  • … mientras iterador es un objeto que define cómo hacer realmente la iteración – específicamente cual es el siguiente elemento. Es por eso que debe tener
    next() método.

Los iteradores también son iterables, con la distinción de que sus __iter__() método devuelve el mismo objeto (self), independientemente de si sus artículos han sido consumidos por llamadas anteriores a next().


Entonces, ¿qué piensa el intérprete de Python cuando ve for x in obj: ¿declaración?

Mira un for círculo. Parece un trabajo para un iterador … Consigamos uno. … hay esto obj chico, así que preguntémosle.

“Sres. obj, ¿tienes tu iterador? “(… llama iter(obj), que llama
obj.__iter__(), que felizmente entrega un nuevo iterador brillante _i.)

Bien, eso fue fácil … Empecemos a iterar entonces. (x = _i.next()x = _i.next()…)

Dado que el Sr. obj tuvo éxito en esta prueba (al hacer que cierto método devuelva un iterador válido), lo recompensamos con un adjetivo: ahora puede llamarlo “iterable Mr. obj“.

Sin embargo, en casos simples, normalmente no se beneficia de tener un iterador y un iterable por separado. Entonces tu defines solo uno objeto, que también es su propio iterador. (A Python realmente no le importa _i entregado por obj no era tan brillante, pero solo el obj sí mismo.)

Es por eso que en la mayoría de los ejemplos que he visto (y lo que me había confundido una y otra vez), puede ver:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

en vez de

class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

Sin embargo, hay casos en los que puede beneficiarse de tener un iterador separado del iterable, como cuando desea tener una fila de elementos, pero más “cursores”. Por ejemplo, cuando desee trabajar con elementos “actuales” y “próximos”, puede tener iteradores separados para ambos. O varios subprocesos que se extraen de una lista enorme: cada uno puede tener su propio iterador para recorrer todos los elementos. Vea las respuestas de @ Raymond y @ glglgl arriba.

Imagina lo que podrías hacer:

class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

Notas:

  • Repetiré de nuevo: el iterador no es iterable. El iterador no se puede utilizar como “fuente” en for círculo. Qué for bucle principalmente necesita es __iter__()
    (que devuelve algo con next()).

  • Por supuesto, for no es el único ciclo de iteración, por lo que lo anterior también se aplica a algunas otras construcciones (while…).

  • Del iterador next() puede lanzar StopIteration para detener la iteración. Sin embargo, no tiene que hacerlo, puede iterar para siempre o usar otros medios.

  • En el “proceso de pensamiento” anterior, _i realmente no existe. Me he inventado ese nombre.

  • Hay un pequeño cambio en Python 3.x: next() método (no el integrado) ahora debe llamarse __next__(). Sí, debería haber sido así todo el tiempo.

  • También puede pensarlo así: iterable tiene los datos, el iterador extrae el siguiente elemento

Descargo de responsabilidad: No soy desarrollador de ningún intérprete de Python, por lo que realmente no sé qué “piensa” el intérprete. Las reflexiones anteriores son únicamente una demostración de cómo entiendo el tema a partir de otras explicaciones, experimentos y experiencias de la vida real de un novato en Python.

Si estás contento con lo expuesto, tienes el poder dejar una división acerca de qué te ha impresionado de este escrito.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *