1

What is the difference between

for i in range(0,3): print cons[i]['fun'](x0)

and

for f in cons: print f['fun'](x0)

where cons is defined as following

A = np.asmatrix([[1,0,0],[0,1,0],[0,0,1]])
x0 = np.asarray([1,2,0])
cons = list()
for i in range(0,3): cons.append({'fun':lambda x: np.dot(A[i],x)})
user2546580
  • 155
  • 1
  • 1
  • 4

1 Answers1

4

Your problem probably is related to the fact that you are having a lambda clause using an unbound variable (i). Change your code like this:

for i in range(0,3): cons.append({'fun':lambda x, i=i: np.dot(A[i],x)})

(I. e. just insert that , i=i.)

This way the value of i is part of the lambda clause and not taken from the surrounding scope.

Alfe
  • 56,346
  • 20
  • 107
  • 159
  • Thanks! that fixed it. So if I understand this correctly, every time that 'i' increments it updates 'A[i]' for the previous entry in the list as well? – user2546580 Jul 03 '13 at 13:42
  • Accepting would be nice, but there's an open question; here my response: Yes. All the lambdas you create are dependent from a variable named `i` which they don't hold themselves. The value of `i` in the surrounding scope determines the outcome at evaluation time. If at this time there is no `i` in the surrounding scope, you'll get an exception. – Alfe Jul 04 '13 at 10:56
  • Not the surrounding scope, but the *enclosing* scope. The original `i` from the loop used to populate `cons`, is the variable that will be used for the closure. After that loop has run, it has the value `2`. Given `for i in range(0,3): print cons[i]['fun'](x0)`, it will change - because the same `i` from the same scope is being reassigned. `for f in cons: print f['fun'](x0)` on the other hand will keep using the `2` value. – Karl Knechtel Aug 16 '22 at 01:48