Ihre lambda
Funktion erfasst eine Variable i
aus dem umgebenden Bereich. Wie in this question beschrieben, ist dieser Umfang der Umfang des Verständnisses.
Ihre Schleife durchläuft nacheinander die Elemente des Generators und ruft jede einzelne vor dem Weiterschalten des Generators auf. Wenn Sie die erste Funktion erhalten, wird der Generator in einem Zustand angehalten, in dem i
0 ist, also das ist der Wert, den die Funktion sieht. Wenn Sie den Generator vorrücken, setzt er i
auf 1, und Sie erhalten eine Funktion, die diesen Wert ergreift. Der Generator "wartet" auf i
, bis Sie zur nächsten Funktion wechseln.
Im Listenverständnis erhalten Sie alle Funktionen auf einmal. Aber alle verweisen immer noch auf die gleiche Variable i
innerhalb des Verständnisbereichs. Da das Listenverstehen den ganzen Weg bis zum Ende geht, geht i
den ganzen Weg bis 4, bevor Sie die Möglichkeit haben, irgendeine der Funktionen zu benutzen.
In beiden Fällen referenziert Ihr Lambda eine Variable im Verständnisbereich. Es ist nur so, dass diese Variable im Generator-Verständnis nicht vorrückt, nachdem Sie die vorherige Funktion bereits aufgerufen haben. Sie können ein ähnliches Verhalten wie die Liste Verständnis Fall sehen, wenn Sie die erste Funktion speichern, aber nennen Sie es erst, nachdem Sie den Generator wieder vorrücken:
def create_funcs():
return (lambda: i for i in range(5))
gen = create_funcs()
f1 = next(gen)
f2 = next(gen)
print(f1())
print(f2())
Der Ausgang ist
1
1
Seit Ich erweiterte den Generator, i
ist 1, also beide f1
und f2
sehen diesen Wert, wenn sie aufgerufen werden. Sie können die gleiche Sache sehen, wenn Sie for f in list(create_funcs())
tun und den Generator zwingen, den ganzen Weg zum Ende zu gehen, wie das Listenverstehen tut.
@BrenBarn: Tut mir leid, ich verstehe nicht, wie die Antwort der anderen Frage bezieht sich auf meine. –
Schauen Sie insbesondere auf [diese Antwort] (http://stackoverflow.com/questions/4575698/python-list-comprehension-overriding-value/4575866#4575866). – BrenBarn
@BrenBarn: OK, aber ich bin auf Python3.5, also warum würde es lecken? –