In <[EMAIL PROTECTED]>, Tim Chase wrote: > My understanding is that the lambda-defined functions are not > called until the actual application thereof, with the > > mypolys = make_polys(8) > mypolys[5](2) #the lambda call happens here, no?
Yes, that's right. > </F>'s original statement read like a koan...there was more in it > than I was getting out of it. There seem to be several concepts > I've not yet wrapped my head around. My understanding (likely > wrong) was that "lambda" was sort of like defining a function > inline, along the lines of > > def f(x): > return x+5 > > being somewhat equiv to > > k = lambda x: x+5 > > you could then do > > >>> f(20) > 25 > >>> j = f > >>> j(20) > 25 > >>> k(20) > 25 > >>> j = k > >>> j(20) > 25 > > There does seem to be some subtle difference, as > > >>> f > <function f at 0xb7d87e9c> > >>> k > <function <lambda> at 0xb7d8c0d4> > > "k" clearly knows it's a <lambda> just as "f" knows its an "f" > (whether asked for by the aliased name or not). That understanding is mostly correct. Just that there's no subtile difference. `k` doesn't know it's a lambda function, it's just an ordinary function at this point which happens to have the name '<lambda>'. That's somewhat unusual but it behaves like any ``def``-ed function. > [lightbulb begins to go on...sorta] > > However, in the OP's example, slightly modified, it seems that > polys, even when it doesn't exist in the calling scope, it > doesn't matter. > > >>> def mp(n): > ... p = lambda x: 1 > ... polys = [p] > ... for i in range(n): > ... polys.append(lambda x: polys[i](x)*x) > ... return polys > ... > >>> f = mp(5) > >>> polys > Traceback (most recent call last): > File "<stdin>", line 1, in ? > NameError: name 'polys' is not defined > >>> for p in f: print p(3) > ... > 1 > Traceback (most recent call last): > File "<stdin>", line 1, in ? > File "<stdin>", line 5, in <lambda> > : > : > : > > I'm curious why the very first attempt to call p(3) doesn't bomb > out with the NameError that "polys" wasn't defined before it even > got to the point of attempting to call it. Well, because `polys` does not exist in the module scope. But it exists in the local scope of the functions in `f`. An example: In [2]:def outer(a): .2.: b = 42 .2.: def inner(c): .2.: print a, b, c .2.: print locals() .2.: .2.: return inner .2.: In [3]:f = outer(1) In [4]:f(2) 1 42 2 {'a': 1, 'c': 2, 'b': 42} If `outer` returns `inner` the inner function still has a reference to the locals of the enclosing function. So they won't go away if the outer function returns. `a` and `b` are looked up when `f` is called. That's a problem if you create more than one function in `outer` and use a name from outer's locals that changes: In [7]:def pitfall(): .7.: functions = list() .7.: for i in range(3): .7.: functions.append(lambda: i) .7.: print 'pitfall: i=%d' % i .7.: return functions .7.: In [8]:for function in pitfall(): .8.: print function() .8.: pitfall: i=2 2 2 2 At the time the list with the functions is returned `i` is 2. So if you call any of the functions it looks up this `i`. Ciao, Marc 'BlackJack' Rintsch -- http://mail.python.org/mailman/listinfo/python-list