why is this different?

Gabriel Genellina gagsl-py at yahoo.com.ar
Fri Dec 8 07:46:45 EST 2006


On 7 dic, 22:53, Schüle Daniel <u... at rz.uni-karlsruhe.de> wrote:

> In [38]: f = [lambda:i for i in range(10)]
> In [39]: ff = map(lambda i: lambda : i, range(10))
> In [40]: f[0]()
> Out[40]: 9
> In [41]: f[1]()
> Out[41]: 9
> In [42]: ff[0]()
> Out[42]: 0
> In [43]: ff[1]()
> Out[43]: 1
>
> I don't understand why in the first case f[for all i in 0..9]==9

In the first case, i is a free variable. That means that Python will
get it from other place (the global namespace, likely [surely?])

>>> f=[lambda:i for i in range(10)]
>>> f[0]()
9
>>> i=123
>>> f[0]()
123
>>> print f[0].func_closure
None

In the second case, the inner i is a free variable, but local to its
enclosing scope (outer lambda). It's a closure:
>>> ff = map(lambda i: lambda : i, range(10))
>>> ff[4]()
4
>>> ff[4].func_closure
(<cell at 0x00ACEA90: int object at 0x00995344>,)
>>> i=321
>>> ff[4]()
4

> what is different from (more usefull)
>
> In [44]: f = ["%i" % i for i in range(10)]
> In [45]: f
> Out[45]: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']

This is a simple expression evaluated at each iteration

> doing it like this works again
>
> In [54]: def d(x):
>     ....:     return lambda:x
>     ....:
x inside lambda is a free variable, but since it's local to d, this
becomes a closure:

>>> d(1)
<function <lambda> at 0x00A35EF0>
>>> d(1).func_closure
(<cell at 0x00A2A4F0: int object at 0x00995338>,)

> In [55]: f = [d(i) for i in range(10)]
> In [56]: f[0]()
> Out[56]: 0
> In [57]: f[1]()
> Out[57]: 1
This is similar to the ff example above

> in a C programmer sence I would say there seems to be no "sequence
> point" which would separate "now" from "next"

No, the problem is that C has no way to express a closure; this is a
functional concept absolutely extraneous to the C language.

-- 
Gabriel Genellina




More information about the Python-list mailing list