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


¿Cuáles son las definiciones más básicas de "iterable", "iterador" e "iteración en Python?

He leído múltiples definiciones, pero su significado exacto aún no se entiende.

¿Puede alguien ayudarme con la idea básica?

Author: abccd, 2012-03-27

12 answers

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

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

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

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

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

Un buen lugar para start learning sería la sección de iteradores del tutorial y la sección de tipos iteradores de la página de tipos estándar. Después de entender los conceptos básicos, pruebe la sección iteradores del HOWTO de Programación Funcional.

 401
Author: agf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-08 15:53:46

Aquí está la explicación que uso en la enseñanza de clases de Python:

Un ITERABLE es:

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

Un ITERADOR es un objeto:

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

Notas:

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

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
 266
Author: Raymond Hettinger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-01 21:36:47

Las respuestas anteriores son geniales, pero como la mayoría de lo que he visto, no enfatices la distinción suficiente para personas como yo.

Además, las personas tienden a sentirse "demasiado Python" poniendo definiciones como "X es un objeto que tiene __foo__()" método de antes. Tales definiciones son correctas based se basan en la filosofía de tipeo de pato, pero el enfoque en los métodos tiende a interponerse cuando se trata de entender el concepto en su simplicidad.

Así que agrego mi versión.


En lenguaje natural,

  • la 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, que en pocas palabras, significa que se puede utilizar en iteración, por ejemplo, con un bucle for. ¿Cómo? Usando iterador . Te lo explicaré a continuación.

  • ... mientras que iterador es un objeto que define cómo hacer realmente el iteración specifically específicamente cuál 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 su método __iter__() devuelve el mismo objeto (self), independientemente de si sus elementos han sido consumidos por llamadas anteriores a next().


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

Mira, un bucle for. Parece un trabajo para un iterador... Consigamos uno. ... Hay un tipo obj, así que preguntémosle.

"Sr. obj, ¿tiene su iterador?" (... llama iter(obj), que llama obj.__iter__(), que felizmente entrega un nuevo iterador brillante _i.)

OK, eso fue fácil... Vamos a empezar a iterar entonces. (x = _i.next() ... x = _i.next()...)

Dado que Mr. obj tuvo éxito en esta prueba (al tener cierto método que devuelve 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 iterador e iterable por separado. Así que defines solo un objeto, que también es su propio iterador. (A Python realmente no le importa que _i entregado por obj no fuera tan brillante, sino solo el obj en sí.)

Esta es la razón por la que en la mayoría de los ejemplos que he visto (y lo que me había estado confundiendo una y otra vez), se puede ver:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

En lugar de

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

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

Hay casos, sin embargo, cuando puede beneficiarse de tener iterador separado del iterable, como cuando desea tener una fila de elementos, pero más "cursores". Por ejemplo, cuando desea trabajar con elementos" actuales "y" próximos", puede tener iteradores separados para ambos. O múltiples hilos tirando de una lista enorme: cada uno puede tener su propio iterador para recorrer todos los elementos. Ver @Raymond y @glglgl respuestas anteriores.

Imagina lo que podrías do:

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. Iterador no se puede utilizar como una "fuente" en el bucle for. Lo que for loop necesita principalmente es __iter__() (que devuelve algo con next()).

  • Por supuesto, for no es el único bucle de iteración, por lo que lo anterior se aplica a algunos otros construye también (while...).

  • El iterador next() puede lanzar StopIteration para detener la iteración. No tiene que, sin embargo, puede iterar para siempre o usar otros medios.

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

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

  • También se puede pensar de esta manera: iterable tiene los datos, iterador tira de la siguiente tema

Descargo de responsabilidad: No soy un desarrollador de cualquier intérprete de Python, así que realmente no sé lo que el intérprete "piensa". 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.

 84
Author: Alois Mahdal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 11:55:19

Un iterable es un objeto que tiene un método __iter__(). Que posiblemente puede repetirse varias veces, como {[2] s}y tuple()s.

Un iterador es el objeto que itera. Es devuelto por un método __iter__(), se devuelve a sí mismo a través de su propio método __iter__() y tiene un método next() (__next__() en 3.x).

La iteración es el proceso de llamar a este next() resp. __next__() hasta que suba StopIteration.

Ejemplo:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1
 20
Author: glglgl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-06 22:01:07

No se si ayuda a alguien pero siempre me gusta visualizar conceptos en mi cabeza para entenderlos mejor. Así que como tengo un hijo pequeño visualizo el concepto iterable/iterador con ladrillos y papel blanco.

Supongamos que estamos en el cuarto oscuro y en el piso tenemos ladrillos para mi hijo. Ladrillos de diferente tamaño, color, no importa ahora. Supongamos que tenemos 5 ladrillos como esos. Esos 5 ladrillos se pueden describir como un objeto - digamos kit de ladrillos. Podemos hacer muchas cosas con este kit de ladrillos – puede tomar uno y luego tomar segundo y luego tercero, puede cambiar los lugares de ladrillos, poner el primer ladrillo por encima del segundo. Podemos hacer muchas cosas con ellos. Por lo tanto, este kit de ladrillos es un objeto iterable o secuencia como podemos ir a través de cada ladrillo y hacer algo con él. Solo podemos hacerlo como mi pequeño hijo - podemos jugar con un ladrillo a la vez . Así que de nuevo me imagino a mí mismo este kit de ladrillos para ser un iterable.

Ahora recuerda que estamos en el cuarto oscuro. O casi oscuro. La cosa es que no vemos claramente esos ladrillos, de qué color son, de qué forma, etc. Así que incluso si queremos hacer algo con ellos-aka iterar a través de ellos – realmente no sabemos qué y cómo porque es demasiado oscuro.

Lo que podemos hacer es cerca del primer ladrillo – como elemento de un kit de ladrillos – podemos poner un pedazo de papel fluorescente blanco para que podamos ver dónde está el primer ladrillo-elemento es. Y cada vez que tomamos un ladrillo de un kit, reemplazamos el pedazo de papel blanco por un ladrillo siguiente para poder verlo en el cuarto oscuro. Este pedazo de papel blanco no es más que un iterador . Es un objeto también . Pero un objeto con lo que podemos trabajar y jugar con elementos de nuestro kit iterable object – bricks.

Eso por cierto explica mi error temprano cuando probé lo siguiente en un IDLE y obtuve un TypeError:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

Lista X aquí estaba nuestro kit de ladrillos, pero NO un pedazo de papel blanco. Necesitaba encontrar un iterador primero:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

No sé si ayuda, pero me ayudó. Si alguien pudiera confirmar/corregir la visualización del concepto, estaría agradecido. Me ayudaría a aprender más.

 8
Author: Nikolay Dudaev,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-09-30 12:25:25

Aquí está mi hoja de trucos:

 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+

Prueba: ¿ves cómo...

  • cada iterador es un iterable?
  • el método __iter__() de un objeto contenedor se puede implementar como generador?
  • ¿un método iterable más un método __next__ no es necesariamente un iterador?
 4
Author: AXO,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-04 10:31:02

No creo que puedas hacerlo mucho más simple que la documentación , sin embargo intentaré:

  • Iterable es algo que puede ser iterado encima. En la práctica, generalmente significa una secuencia por ejemplo, algo que tiene un principio y un fin y alguna forma de pasar por todos los elementos en él.
  • Se puede pensar Iterador como un pseudo-método auxiliar (o pseudo-atributo) que da (o mantiene) el siguiente (o primer) elemento en el iterable. (En la práctica es solo un objeto que define el método next())

  • La iteración probablemente se explica mejor por la definición de la palabra Merriam-Webster :

B: la repetición de una secuencia de instrucciones de la computadora número de veces o hasta que se cumple una condición - compare recursion

 3
Author: Kimvais,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-27 06:23:36
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

Así que,

  1. iterable es un object que puede ser somete a. por ejemplo, lista, cadena, tupla, etc.

  2. Usando la función iter en nuestro objeto iterable devolverá un objeto iterador .

  3. Ahora este objeto iterador tiene un método llamado __next__ (en Python 3, o simplemente nexten Python 2) por el cual puede acceder a cada elemento de iterable.

So, LA SALIDA DEL CÓDIGO ANTERIOR SERÁ BE:

1

2

 1
Author: arpan kumar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-24 14:40:33

Antes de tratar con los iterables y el iterador, el factor principal que decide el iterable y el iterador es la secuencia

Secuencia: La secuencia es la colección de datos

Iterable:Iterable son los objetos de tipo secuencia que soportan el método Iter.

Método Iter: El método Iter toma la secuencia como entrada y crea un objeto que se conoce como iterador

Iterador:El iterador es el objeto que llama al método siguiente y atraviesa la secuencia.En llamar a la siguiente método devuelve el objeto que ha transversal actualmente.

Ejemplo:

x=[1,2,3,4]

X es una secuencia que consiste en la recopilación de datos

y=iter(x)

Al llamar a iter(x) devuelve un iterador solo cuando el objeto x tiene el método iter, de lo contrario, genera una excepción.Si devuelve el iterador entonces y se asigna así:

y=[1,2,3,4]

Como y es un iterador, soporta el método next ()

Al llamar al método siguiente devuelve los elementos individuales de la lista uno por una.

Después de devolver el último elemento de la secuencia, si volvemos a llamar al siguiente método, se genera un error de StopIteration

Ejemplo:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration
 1
Author: Shadow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-28 09:04:07

Iterable:- algo que es iterable es iterable; como secuencias como listas ,cadenas, etc. También tiene el método __getItem__() o una función iter() que devuelve un iterador.

Iterador:- Cuando obtenemos el objeto iterador del método iter() de iterable; llamamos al método __next__() (en python3) o simplemente next() (en python2) para obtener elementos uno por uno. Esta clase o instancia de esta clase se denomina iterador.

Desde docs:-

El uso de iteradores impregna y unifica Python. Entre bastidores, la instrucción for llama a iter() en el objeto contenedor. La función devuelve un objeto iterador que define el método __next__() que accede a los elementos del contenedor de uno en uno. Cuando no hay más elementos, __next__() genera una excepción de StopIteration que le dice al bucle for que termine. Puede llamar al método __next__() usando la función incorporada next(); este ejemplo muestra cómo todo obras:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

Ex de una clase: -

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s
 1
Author: Vicrobot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-20 04:50:37

Los iterables tienen un método __iter__ que instanciaun nuevo iterador cada vez.

Los iteradores implementan un método __next__ que devuelve elementos individuales, y un método __iter__ que devuelve self.

Por lo tanto, los iteradores también son iterables, pero los iterables no son iteradores.

Luciano Ramalho, Python fluido.

 0
Author: trthhrtz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-06 11:10:36

En Python todo es un objeto. Cuando se dice que un objeto es iterable, significa que puede recorrer (es decir, iterar) el objeto como una colección.

Los arrays, por ejemplo, son iterables. Puede pasar a través de ellos con un bucle for, y pasar del índice 0 al índice n, n es la longitud del objeto de matriz menos 1.

Los diccionarios (pares de clave/valor, también llamados arrays asociativos) también son iterables. Puedes pasar a través de sus llaves.

Obviamente los objetos que son no las colecciones no son iterables. Un objeto bool, por ejemplo, solo tiene un valor, Verdadero o Falso. No es iterable (no tendría sentido que sea un objeto iterable).

Leer más. http://www.lepus.org.uk/ref/companion/Iterator.xml

 -6
Author: user93097373,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-07-15 08:59:16