169 votes

Comportement de l'itérateur de liste Python et next (itérateur)

Considérer:

>>> lst = iter([1,2,3])
>>> next(lst)
1
>>> next(lst)
2

Donc, avance l'itérateur est, comme prévu, géré par la mutation de ce même objet.

Ceci étant le cas, je l'espère:

a = iter(list(range(10)))
for i in a:
   print(i)
   next(a)

pour passer chaque deuxième élément: l'appel à l' next devrait avance l'itérateur une fois, puis l'appel implicite faite par la boucle avance une deuxième fois, et le résultat de ce deuxième appel sera affecté à la i.

Il n'a pas. La boucle imprime tous les éléments dans la liste, sans en sauter aucune.

Ma première pensée a été que cela peut se produire parce que la boucle appels iter sur ce qui s'est passé, et cela pourrait donner un indépendant itérateur - ce n'est pas le cas, comme nous l'avons iter(a) is a.

Alors, pourquoi est - next apparaît pas à l'avance l'itérateur dans ce cas?

225voto

Martijn Pieters Points 271458

Ce que vous voyez est l' interprète en renvoyant la valeur de retour de l' next():

>>> a = iter(list(range(10)))
>>> for i in a:
...    print(i)
...    next(a)
... 
0
1
2
3
4
5
6
7
8
9

Si vous affectez la sortie d' next() les choses fonctionnent comme prévu:

>>> a = iter(list(range(10)))
>>> for i in a:
...    print(i)
...    _ = next(a)
... 
0
2
4
6
8

ou imprimer des informations supplémentaires:

>>> a = iter(list(range(10)))
>>> for i in a:
...    print('Printing: {}'.format(i))
...    next(a)
... 
Printing: 0
1
Printing: 2
3
Printing: 4
5
Printing: 6
7
Printing: 8
9

En d'autres termes, next() fonctionne comme prévu, mais parce qu'elle renvoie la valeur de l'itérateur, vous êtes amené à croire que la boucle a son propre itérateur copie en quelque sorte.

16voto

njzk2 Points 17085

Ce qui se passe, c'est que next(a) renvoie la valeur suivante de a, qui est imprimée sur la console car elle n'est pas affectée.

Ce que vous pouvez faire, c'est affecter une variable avec cette valeur:

 >>> a = iter(list(range(10)))
>>> for i in a:
...    print(i)
...    b=next(a)
...
0
2
4
6
8
 

11voto

klm Points 116

Je trouve les questions / réponses un peu confus, parce qu'ils ne sont qu'indirectement indiquer l'essentiel de la mystifier chose dans l'exemple de code: les deux* pour l'impression "je" et le "prochaine(a)" sont à l'origine de leurs résultats à l'impression.

Depuis qu'ils ont l'impression de alternant les éléments de la séquence d'origine, et c'est inattendu que "la prochaine(a)" l'instruction est en cours d'impression, il semble que l'impression "je" de l'énoncé est l'impression de toutes les valeurs.

Dans cette perspective, il devient de plus en plus clair que l'affectation de résultat de la "prochaine(a)" à une variable inhibe l'impression de son résultat, de façon à ce que les valeurs autres que le "je" variable de boucle sont imprimés. De la même manière, de faire le "print" déclaration émettent quelque chose de plus distinctif disambiguates, ainsi.

(L'un de ces réponses réfute les autres parce que la réponse est d'avoir le code d'exemple évalué comme un bloc, de sorte que l'interprète n'est pas de déclaration les valeurs intermédiaires pour "next ()".)

La séduisante chose en répondant aux questions, en général, est explicite sur ce qui est évident, une fois que vous connaissez la réponse. Il peut être difficile à atteindre. De même, la critique des réponses une fois que vous les comprenez. Il est intéressant...

1voto

Inbar Rose Points 13033

Quelque chose ne va pas avec votre Python / ordinateur.

 a = iter(list(range(10)))
for i in a:
   print(i)
   next(a)

>>> 
0
2
4
6
8
 

Fonctionne comme prévu.

Testé en Python 2.7 et en Python 3+. Fonctionne correctement dans les deux

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