Python Language
Iterables e iteradores
Buscar..
Iterador vs Iterable vs generador
Un iterable es un objeto que puede devolver un iterador . Cualquier objeto con estado que tenga un método __iter__
y devuelva un iterador es iterable. También puede ser un objeto sin estado que implemente un método __getitem__
. - El método puede tomar índices (comenzando desde cero) y generar un IndexError
cuando los índices ya no son válidos.
La clase str
de Python es un ejemplo de __getitem__
iterable.
Un iterador es un objeto que produce el siguiente valor en una secuencia cuando llama al next(*object*)
en algún objeto. Además, cualquier objeto con un método __next__
es un iterador. Un iterador genera StopIteration
después de agotar el iterador y no se puede reutilizar en este punto.
Clases iterables
Las clases __iter__
definen un __iter__
y __next__
. Ejemplo de una clase iterable:
class MyIterable:
def __iter__(self):
return self
def __next__(self):
#code
#Classic iterable object in older versions of python, __getitem__ is still supported...
class MySequence:
def __getitem__(self, index):
if (condition):
raise IndexError
return (item)
#Can produce a plain `iterator` instance by using iter(MySequence())
Intentando crear una instancia de la clase abstracta del módulo de collections
para ver mejor esto.
Ejemplo:
import collections
>>> collections.Iterator()
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods __next__
Maneje la compatibilidad de Python 3 para las clases iterables en Python 2 haciendo lo siguiente:
class MyIterable(object): #or collections.Iterator, which I'd recommend....
....
def __iter__(self):
return self
def next(self): #code
__next__ = next
Ambos son ahora iteradores y se pueden pasar a través de:
ex1 = MyIterableClass()
ex2 = MySequence()
for (item) in (ex1): #code
for (item) in (ex2): #code
Los generadores son formas simples de crear iteradores. Un generador es un iterador y un iterador es un iterable.
Lo que puede ser iterable
Iterable puede ser cualquier cosa por la cual los artículos se reciben uno por uno, solo hacia adelante . Las colecciones Python incorporadas son iterables:
[1, 2, 3] # list, iterate over items
(1, 2, 3) # tuple
{1, 2, 3} # set
{1: 2, 3: 4} # dict, iterate over keys
Los generadores devuelven iterables:
def foo(): # foo isn't iterable yet...
yield 1
res = foo() # ...but res already is
Iterando sobre todo iterable
s = {1, 2, 3}
# get every element in s
for a in s:
print a # prints 1, then 2, then 3
# copy into list
l1 = list(s) # l1 = [1, 2, 3]
# use list comprehension
l2 = [a * 2 for a in s if a > 2] # l2 = [6]
Verificar solo un elemento en iterable.
Utilice el desembalaje para extraer el primer elemento y asegurarse de que sea el único:
a, = iterable
def foo():
yield 1
a, = foo() # a = 1
nums = [1, 2, 3]
a, = nums # ValueError: too many values to unpack
Extraer valores uno por uno.
Comience con iter()
incorporado para obtener iterador sobre iterable y use next()
para obtener elementos uno por uno hasta que se StopIteration
para StopIteration
el final:
s = {1, 2} # or list or generator or even iterator
i = iter(s) # get iterator
a = next(i) # a = 1
b = next(i) # b = 2
c = next(i) # raises StopIteration
¡El iterador no es reentrante!
def gen():
yield 1
iterable = gen()
for a in iterable:
print a
# What was the first item of iterable? No way to get it now.
# Only to get a new iterator
gen()