2015-03-25 20 views
7

Ich habe Probleme damit, lambdas zu arbeiten. Der Code hier ist ein Beispiel, aber es zeigt mein Problem gut.Warum funktionieren meine Lambdas nicht?

lambdas = list() 

for i in range(5): 
    lambdas.append(lambda x:i*i*x) 


print lambdas[0](1) 
print lambdas[2](1) 

Das gibt mir 16, aber ich erwarte unterschiedliche Werte für verschiedene Lambda. Warum passiert?

+0

"Scope in Python ist lexikalisch. Eine Schließung wird immer den Namen und den Umfang der Variablen merken, nicht das Objekt, auf das sie zeigt." http://stackoverflow.com/questions/2295290/what-do-lambda-funktion-closures-capture-in-python Ihr Lambda erfasst den Namen "i", nicht den Objektwert *, auf den "i" verweist. – Shashank

Antwort

9

In diesem Code:

for i in range(5): 
    lambdas.append(lambda x:i*i*x) 

Der Wert i wird bestimmt, wenn die Funktion Lauf ist . Der Wert i, wenn die Funktion definiert ist, ist verloren.

Verwenden statt:

lambdas = list() 

for i in range(5): 
    lambdas.append(lambda x, i=i : i*i*x) 

print lambdas[0](1) 
print lambdas[2](1) 

Dies erzeugt:

0 
4 

Dies funktioniert, weil, als Sonderfall, die Standardargumente auf eine Funktion, wie in i=i oben, sofort binden.

+0

Eine Erklärung, warum es ursprünglich nicht funktioniert hat, wäre eine gute Antwort. Aber ich mag das Standardargument instant bind. – Serdalis

+1

@Serdalis Gute Idee. Erklärung hinzugefügt. – John1024

6

i ist 4 wenn Ihre Schleife endet, so i ist 4 für jede lambda.

Wenn Sie i außerhalb der Schleife gedruckt werden Sie sehen, es ist 4:

for i in range(5): 
    lambdas.append(lambda x: i * i * x) 

print(i) 
4 

Sie eine Variable verwenden, die in der gesamten Schleife aktualisiert wird, wenn Sie das Lambda innerhalb der Schleife nennen würden Sie bekommen, was du hast erwartet.

for i in range(5): 
    lambdas.append(lambda x: i * i * x) 
    print(lambda x: i * i * x)(1) 
0 
1 
4 
9 
16 

Das Verhalten ist das, was man erwarten würde, i einfach eine Variable wie jede andere ist.

Auf einer Seite beachten Sie eine Liste comp Ihre Liste zu erstellen, verwenden:

lambdas = [lambda x,i=i: i * i * x for i in xrange(5)] 
Verwandte Themen