They are different, because the value of i
in both the generator expression and the list comp are evaluated lazily, i.e. when the anonymous functions are invoked in f
.
By that time, i
is bound to the last value if t
, which is -1.
So basically, this is what the list comprehension does (likewise for the genexp):
x = []
i = 1 # 1. from t
x.append(lambda: i)
i = -1 # 2. from t
x.append(lambda: i)
Now the lambdas carry around a closure that references i
, but i
is bound to -1 in both cases, because that is the last value it was assigned to.
If you want to make sure that the lambda receives the current value of i
, do
f(*[lambda u=i: u for i in t])
This way, you force the evaluation of i
at the time the closure is created.
Edit: There is one difference between generator expressions and list comprehensions: the latter leak the loop variable into the surrounding scope.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…