web-dev-qa-db-fra.com

Confondu avec python listes: sont-ils ou ne sont-ils pas des itérateurs?

J'étudie Alex Marteli Python en bref et le livre suggère que tout objet qui a une méthode next() est (ou au moins peut être utilisé comme) un 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 ceci dans le livre, j'ai ressenti le besoin de l'essayer. J'ai lancé un interpréteur python 2.7.3 et j'ai fait ceci:

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

Cependant, le résultat était 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 avait un objet fonction __iter__. J'ai donc compris qu'il peut être utilisé comme itérateur, tant qu'il prend en charge ce type d'interface.

Donc, quand j'ai réessayé, cette fois légèrement différemment, en essayant de faire ceci:

>>> _temp_iter = next(x)

J'ai eu cette erreur:

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

Mais comment une liste NE peut-elle PAS être un itérateur, car elle semble prendre en charge cette interface et peut certainement être utilisée comme une dans le contexte suivant:

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

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

66
NlightNFotis

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

90

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 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
22
Ashwini Chaudhary

Juste au cas où vous seriez confus quant à 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 implémente le protocole itérateur:

  • __iter__ méthode
  • next méthode

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

D'un autre côté, les objets itérables implémentent le __iter__ méthode qui, lorsqu'elle est appelée, renvoie un itérateur, qui permet plusieurs passages sur leurs données. Les objets itérables sont réutilisables, une fois épuisés, ils peuvent être réitérés. Ils peuvent être convertis en itérateurs à l'aide de la fonction iter.

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 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,
>>> 
18
Vicent

La liste n'est pas un itérateur mais list contient un objet itérateur __iter__ Donc lorsque vous essayez d'utiliser for loop sur n'importe quelle liste, pour les appels de boucle __iter__, La méthode obtient l'objet itérateur et ensuite il utilise next () méthode de liste.

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

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

4
Kaushal