Un objeto iterable es aquel que puede devolver un iterador. Normalmente las colecciones que hemos estudiados son iterables. Un iterador me permite recorrer los elementos del objeto iterable.
>>> iter1 = iter([1,2,3])
>>> type(iter1)
<class 'list_iterator'>
>>> iter2 = iter("hola")
>>> type(iter2)
<class 'str_iterator'>
Para recorrer el iterador, utilizamos la función next()
:
>>> next(iter1)
1
>>> next(iter1)
2
>>> next(iter1)
3
>>> next(iter1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
La función reversed()
devuelve un iterador con los elementos invertidos, desde el último al primero.
>>> iter2 = reversed([1,2,3])
>>> next(iter2)
3
>>> next(iter2)
2
>>> next(iter2)
1
>>> next(iter2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
El módulo itertools contiene distintas funciones que nos devuelven iteradores.
Veamos algunos ejemplos:
count()
: Devuelve un iterador infinito.
>>> from itertools import count
>>> counter = count(start=13)
>>> next(counter)
13
>>> next(counter)
14
cycle()
: devuelve una secuencia infinita.
>>> from itertools import cycle
>>> colors = cycle(['red', 'white', 'blue'])
>>> next(colors)
'red'
>>> next(colors)
'white'
>>> next(colors)
'blue'
>>> next(colors)
'red'
islice()
: Retorna un iterador finito.
>>> from itertools import islice
>>> limited = islice(colors, 0, 4)
>>> for x in limited:
... print(x)
white
blue
red
white
Un generador es un tipo concreto de iterador. Es una función que permite obtener sus resultados paso a paso. Por ejemplo, hacer una función que cada vez que la llamemos nos de el próximo número par. Tenemos dos maneras de crear generadores:
-
Realizar una función que devuelva los valores con la palabra reservada
yield
. Lo veremos con profundidad cuando estudiemos las funciones. -
Utilizando la sintaxis de las "list comprehension". Por ejemplo:
>>> iter1 = (x for x in range(10) if x % 2==0) >>> next(iter1) 0 >>> next(iter1) 2 >>> next(iter1) 4