list of polynomial functions

Tim Chase python.list at
Thu Jun 15 19:04:04 EDT 2006

> Just to be a bit more explicit:
> In code like:
>      def make_polys(n):
>          """Make a list of polynomial functions up to order n."""
>          p = lambda x: 1
>          polys = [p]
>          for i in range(n):
>              polys.append(lambda x: polys[i](x)*x)
>          i=3
> The lambda-defined functions will be called after the for loop is done,


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?

</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)
	>>> j = f
	>>> j(20)
	>>> k(20)
	>>> j = k
	>>> j(20)

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).

So at some point, the Python interpreter is compiling this 
function/lambda, and expanding matters with or without some sort 
of scope.  The OP's example seems to pull both "polys" and "i" 
from the local scope.  However, Python must only be tokenizing 
and making references to future-ly available stuff, as, without 
"spam", "blah", "tapioca", or "spatula" defined in my 
environment, I can do arbitrary things like

	q = lambda x: spam[spatula](x) + blah / tapioca

and Python swallows the whole lot as syntactically kosher, even 
though none of these items exist.  It seems to only evaluate them 
at the point that "q" is called.

[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)
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.

> Hope this makes it a bit clearer.

like chocolate. :-/

Thanks for trying though...

-tkc (who is certainly *not* a LISP programmer, as evidenced here...)

More information about the Python-list mailing list