On 2006-04-21, Ben C <[EMAIL PROTECTED]> wrote: > On 2006-04-21, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote: >> Hello, >> >> I need your help understanding lambda (and doing it a better way >> without). >> >> f = lambda x : x*x >> [...] >> # the idea is now to give the definition of the multiplication of >> functions and integers >> # (f * c)(xx) := f(x)*c >> [lambda xx: f(xx)*y for y in range(1,5)][0](1) >> # returns 4 >> # I would expect 1*x*x = 1 > > If you change the 5 in range(1,5) to a 10, this returns 9. > > So it looks like each of the lambda xx : f(xx) * y is getting the last > value of y. > > I can do this for example: > > f = lambda x : x * x > fns = [lambda xx: f(xx)*y for y in range(1,10)] > for fn in fns: > print fn(1) > > And I get 9 printed out 9 times. > > It does seem a bit surprising, but I suppose if you think about it > there's only one "y"-- the one in the outer scope. This one variable is > bound 9 times, to a new value each time. > > What one would need for it to work would be for each of the functions to > have a variable in its own scope. But you can't, as far as I know, > create local variables in functions defined with lambda.
Having said that, I attempted to confirm this using def rather than lambda, and encountered something I cannot explain at all-- it appears that the functions are getting redefined whenever they are called, to effect a kind of "dynamic scoping" behaviour. I would appreciate any explanation anyone can give of this: fns = [] for y in range(2): def fn(): yy = y # exactly the same with yy = int(y) print "defining fn that returns", yy return yy print "Appending at", y print fn, fn() fns.append(fn) print "OK" for fn in fns: print "Calling", fn print fn, fn() y = 10 for fn in fns: print "Calling", fn print fn, fn() The output: Appending at 0 <function fn at 0x402e317c> defining fn that returns 0 0 Appending at 1 <function fn at 0x402e31b4> defining fn that returns 1 1 OK Calling <function fn at 0x402e317c> <function fn at 0x402e317c> defining fn that returns 1 1 Calling <function fn at 0x402e31b4> <function fn at 0x402e31b4> defining fn that returns 1 1 Calling <function fn at 0x402e317c> <function fn at 0x402e317c> defining fn that returns 10 10 Calling <function fn at 0x402e31b4> <function fn at 0x402e31b4> defining fn that returns 10 10 -- http://mail.python.org/mailman/listinfo/python-list