Theoretical question about Lambda
Paul Foley
see at below
Mon May 6 07:20:26 EDT 2002
On Mon, 06 May 2002 07:10:14 GMT, Alex Martelli wrote:
>>>> funs=[lambda:x for x in range(5)]
>>>> [f() for f in funs]
> [4, 4, 4, 4, 4]
>>>> funs=[lambda x=x:x for x in range(5)]
>>>> [f() for f in funs]
> [0, 1, 2, 3, 4]
> But actually with the first form you get 5 functions that all return
> *whatever value name x is currently bound to*, NOT functions that return
> the last value in seq:
Oh, right, I knew that...just temporarily forgot that the x introduced
by the listcomp "leaks" out. But you can write it as
from __future__ import nested_scopes
def getfns(seq):
return [(lambda: x) for x in seq]
funs = getfns([1,2,3,4,5])
so that the x in the listcomp doesn't leak into the global
environment, and the lambda does form a closure. You still get a list
of functions that all return 5.
> The 'closure' alternative which I also posted and you snipped is superior
> to either lambda alternative because it 'snapshots' state like the second
> of these lambda variations but doesn't squirrel it away in the fragile spot
> of "a default value for an argument" (risking somebody mistakenly supplying
> an argument and thus overriding the default...:-).
Well, I assumed you were using nested_scopes, so this wasn't an issue.
>> [The usual binding-vs-assignment misunderstanding that I keep trying
>> to explain to people who say Python's assignment is really "binding"]
> I'm one of those people to which you "keep trying to explain" and I'm
> deeply unconvinced by your explanations. Assignment rebinds names
OK; question: what's the difference, if any, between
x = n
do_something
and
def foo(x):
do_something
foo(n)
as far as x is concerned?
Given that (lambda: x) /does/ close over x with nested scopes enabled,
can you explain why
fns = getfns(seq)
produces a list of functions that all return seq[-1]? And why, as you
point out,
def getfns2(seq):
return [(lambda x=x: x) for x in seq]
produces functions that return all the elements of seq?
[Assume you call them with no arguments!]
--
Nonono, while we're making wild conjectures about the behavior of
completely irrelevant tasks, we must not also make serious mistakes,
or the data might suddenly become statistically valid.
-- Erik Naggum
(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(#\@) "actrix.gen.nz>"))
More information about the Python-list
mailing list