2016-08-08 24 views
3

Ich übte die yield Aussage. Ich habe die folgende Funktion in Python geschrieben 2.7:Warum zeigt next() immer denselben Wert an?

>>> def mygen(): 
...  i = 0 
...  j = 3 
...  for k in range(i, j): 
...   yield k 
... 
>>> mygen().next() 
0 
>>> mygen().next() 
0 
>>> mygen().next() 
0 

Jedes Mal, wenn ich rufe die mygen().next() es immer ausgegeben als 0 zeigt, statt 0, 1, 2 & StopIteration. Kann mir bitte jemand das erklären?

Antwort

10

Sie sind Erneut der Generator jedes Mal, so dass es von Anfang an jedes Mal beginnt.

Erstellen Sie den Generator einmal:

gen = mygen() 
gen.next() 
gen.next() 
gen.next() 

Generator-Funktionen ein neues Iterator erzeugen jedes Mal, wenn sie nennen; Auf diese Weise können Sie mehrere unabhängige Kopien erstellen. Jeder unabhängige Iterator ist ein Aufruf der Funktion, die durch separat verstärkt werden kann von den anderen:

>>> def mygen(): 
...  i = 0 
...  j = 3 
...  for k in range(i, j): 
...   yield k 
... 
>>> gen1 = mygen() 
>>> gen2 = mygen() 
>>> gen1.next() 
0 
>>> gen1.next() 
1 
>>> gen2.next() 
0 
>>> gen2.next() 
1 
>>> gen1.next() 
2 
>>> gen1.next() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

Beachten Sie, dass Sie wahrscheinlich die next() function statt Aufruf generator.next() direkt verwenden möchten:

next(gen) 

generator.next() ist als ein Haken (Python 3 hat es in generator.__next__() umbenannt und die next() Funktion ist die offizielle API, um es in einer versionsübergreifenden kompatiblen Weise aufzurufen.

0

Eine Funktionsdefinition, die eine Yield-Anweisung enthält, gibt einen Generator zurück. Sie müssen die nächste Funktion für diesen Generator anstelle der Funktion selbst anwenden. Um zu klären, Ihre Funktion Definition entspricht:

def mygen(): 
     i, j = 0, 3 
     return (k for k in range(i, j)) 

oder:

mygen = lambda :(k for k in range(0, 3)) 

So würden Sie es wie folgt verwenden:

gen1 = mygen() 
    gen2 = mygen() 
    next(gen1) // returns 0 
    next(gen1) // returns 1 
    list(gen1) // returns [2] 
    list(gen2) // returns [0, 1, 2]