lambda

Ben C spamspam at spam.eggs
Fri Apr 21 15:56:01 EDT 2006


On 2006-04-21, Ben C <spamspam at spam.eggs> wrote:
> On 2006-04-21, rubbishemail at web.de <rubbishemail at web.de> 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



More information about the Python-list mailing list