harrismh777 writes: > >>> fs=[] > >>> fs = [(lambda n: i + n) for i in range(10)] > >>> [fs[i](1) for i in range(10)] > [10, 10, 10, 10, 10, 10, 10, 10, 10, 10] <=== not good > > ( that was a big surprise! . . . ) > ( let's try it another way . . . )
The ten functions share the same i. The list comprehension changes the value of that i. At the time when the functions are called, the value is 9. A different list comprehension mechanism could create a fresh i for each element instead of changing the value of one i. Then each of the functions would have a private i which would have the value it had at the time of the creation of the closure. That is not the Python mechanism. The same sharing-an-i thing happens here: >>> fs = [] >>> for i in range(4): ... fs.append(lambda n : i + n) ... >>> fs[0](0) 3 And the different private-j thing happens here: >>> gs = [] >>> for i in range(4): ... gs.append((lambda j : lambda n : j + n)(i)) ... >>> gs[0](0) 0 You used the lambda itself to introduce its private i in your other examples, in (lambda n, i=i : i + n). In its i=i, the i to the left is a different i - will be a fresh i every time the function is called, I think - while the i to the right gets resolved to the value of the i that the list comprehension is stepping at the time when the closure is created. > What is going on with the binding in the first > construct... this seems to reduce the usefulness of lambda to a > considerable extent? The lambda is doing its lambda thing exactly. The list comprehension just updates the one i in whatever you call it that each of the ten closures remember, and they all observe the updates, so to say. It's a bit subtle. Using different names might help, like I used j. -- http://mail.python.org/mailman/listinfo/python-list