87 votes

Confusion avec les listes python : sont-elles ou non des itérateurs ?

J'étudie Python in a Nutshell, d'Alex Marteli et le livre suggère que tout objet qui a une next() est (ou du moins peut être utilisée comme) une méthode de itérateur . Il suggère également que la plupart des itérateurs sont construits par des appels implicites ou explicites à une méthode appelée iter .

Après avoir lu cela dans le livre, j'ai eu envie de l'essayer. J'ai lancé un interpréteur python 2.7.3 et j'ai fait ça :

>>> x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> for number in range(0, 10):
...     print x.next()

Cependant, le résultat a été le suivant :

Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
AttributeError: 'list' object has no attribute 'next'

Dans la confusion, j'ai essayé d'étudier la structure de l'objet x via dir(x) et j'ai remarqué qu'il y avait un __iter__ objet de la fonction. J'ai donc compris qu'il pouvait être utilisé comme un itérateur, pour autant qu'il supporte ce type d'interface.

Alors quand j'ai réessayé, cette fois-ci légèrement différemment, en essayant de faire ça :

>>> _temp_iter = next(x)

J'ai obtenu cette erreur :

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: list object is not an iterator

Mais comment une liste peut-elle NE PAS être un itérateur, puisqu'elle semble supporter cette interface, et peut certainement être utilisée comme telle dans le contexte suivant :

>>> for number in x:
...     print x

Quelqu'un pourrait-il m'aider à clarifier cela dans mon esprit ?

112voto

Ignacio Vazquez-Abrams Points 312628

Ils sont itérable mais ils ne le sont pas. itérateurs . Ils peuvent être transmis à iter() pour obtenir un itérateur pour eux soit implicitement (par exemple via for ) ou explicitement, mais ils ne sont pas des itérateurs en soi.

27voto

Ashwini Chaudhary Points 94431

Vous devez d'abord convertir la liste en un itérateur en utilisant iter() :

In [7]: x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

In [8]: it=iter(x)

In [9]: for i in range(10):
    it.next()
   ....:     
   ....:     
Out[10]: 0
Out[10]: 1
Out[10]: 2
Out[10]: 3
Out[10]: 4
Out[10]: 5
Out[10]: 6
Out[10]: 7
Out[10]: 8
Out[10]: 9

In [12]: 'next' in dir(it)
Out[12]: True

In [13]: 'next' in dir(x)
Out[13]: False

vérifier si un objet est un itérateur ou non :

In [17]: isinstance(x,collections.Iterator)
Out[17]: False

In [18]: isinstance(x,collections.Iterable)
Out[18]: True

In [19]: isinstance(it,collections.Iterable) 
Out[19]: True

In [20]: isinstance(it,collections.Iterator)
Out[20]: True

26voto

Vicent Points 5152

Au cas où vous ne comprendriez pas bien la différence entre les itérables et les itérateurs. Un itérateur est un objet représentant un flux de données. Il met en œuvre le protocole des itérateurs :

  • __iter__ méthode
  • next méthode

Des appels répétés à la méthode next() de l'itérateur renvoient des éléments successifs dans le flux. Lorsque plus de données ne sont disponibles, l'objet itérateur est épuisé et tout autre appel à sa méthode next() ne fait que relancer StopIteration.

D'autre part, les objets itérables mettent en œuvre la fonction __iter__ qui, lorsqu'elle est appelée, renvoie un itérateur, ce qui permet de passer plusieurs fois sur leurs données. Les objets itérables sont réutilisables. Une fois épuisés, ils peuvent être réutilisés par itération. Ils peuvent être convertis en itérateurs à l'aide de la méthode iter fonction.

Donc si vous avez une liste (itérable) vous pouvez faire :

>>> l = [1,2,3,4]
>>> for i in l:
...     print i,
1 2 3 4
>>> for i in l:
...     print i,
 1 2 3 4

Si vous convertissez votre liste en un itérateur :

>>> il = l.__iter__()  # equivalent to iter(l)
>>> for i in il:
...     print i,
 1 2 3 4
>>> for i in il:
...     print i,
>>>

8voto

Kaushal Points 21

La liste n'est pas un itérateur mais la liste contient un objet itérateur. __iter__ donc quand vous essayez d'utiliser la boucle for sur une liste, la boucle for appelle __iter__ et obtient l'objet itérateur, puis utilise la méthode next() de la liste.

x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
it = x.__iter__()

Maintenant it contient un objet itérateur de x que vous pouvez utiliser comme it.next() jusqu'à ce que l'exception StopIteration soit levée

0voto

Tutankhamun Points 119

Il y a déjà de bonnes réponses sur le fait que la liste est un itérable mais pas un itérateur. Dans une version de python > 3.0, utilisez ce qui suit

a = [1, 2, 3]
b = iter(a)
b.__next__()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X