Python Language
Iterables et Iterators
Recherche…
Itérateur vs Iterable vs Générateur
Un iterable est un objet qui peut renvoyer un itérateur . Tout objet avec un état possédant une méthode __iter__
et __iter__
un itérateur est une itération. Il peut également s'agir d'un objet sans état qui implémente une méthode __getitem__
. - La méthode peut prendre des indices (à partir de zéro) et élever une IndexError
lorsque les indices ne sont plus valides.
La classe str
de Python est un exemple d'itérable __getitem__
.
Un itérateur est un objet qui produit la valeur suivante dans une séquence lorsque vous appelez next(*object*)
sur un objet. De plus, tout objet avec une méthode __next__
est un itérateur. Un itérateur déclenche StopIteration
après avoir épuisé l'itérateur et ne peut pas être réutilisé à ce stade.
Classes itérables:
Les classes itérables définissent une __iter__
et une méthode __next__
. Exemple de classe itérable:
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())
Essayer d'instancier la classe abstraite du module de collections
pour mieux voir cela.
Exemple:
import collections
>>> collections.Iterator()
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods next
>>> TypeError: Cant instantiate abstract class Iterator with abstract methods __next__
Gérez la compatibilité de Python 3 pour les classes itérables dans Python 2 en procédant comme suit:
class MyIterable(object): #or collections.Iterator, which I'd recommend....
....
def __iter__(self):
return self
def next(self): #code
__next__ = next
Les deux sont maintenant des itérateurs et peuvent être parcourus en boucle:
ex1 = MyIterableClass()
ex2 = MySequence()
for (item) in (ex1): #code
for (item) in (ex2): #code
Les générateurs sont des moyens simples de créer des itérateurs. Un générateur est un itérateur et un itérateur est une itération.
Qu'est-ce qui peut être itérable
Iterable peut être tout ce dont les éléments sont reçus un par un, en avant uniquement . Les collections Python intégrées sont itérables:
[1, 2, 3] # list, iterate over items
(1, 2, 3) # tuple
{1, 2, 3} # set
{1: 2, 3: 4} # dict, iterate over keys
Les générateurs retournent les itérables:
def foo(): # foo isn't iterable yet...
yield 1
res = foo() # ...but res already is
Itérer sur la totalité des itérables
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]
Vérifier un seul élément dans iterable
Utilisez la décompression pour extraire le premier élément et assurez-vous qu'il est le seul:
a, = iterable
def foo():
yield 1
a, = foo() # a = 1
nums = [1, 2, 3]
a, = nums # ValueError: too many values to unpack
Extraire des valeurs une par une
Commencez avec iter()
intégré pour obtenir un itérateur sur iterable et utilisez next()
pour obtenir les éléments un par un jusqu'à StopIteration
que StopIteration
soit StopIteration
pour StopIteration
la fin:
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
Iterator n'est pas réentrant!
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()