why is this different?

Schüle Daniel uval at rz.uni-karlsruhe.de
Fri Dec 8 00:11:02 EST 2006


Gabriel Genellina schrieb:
Gabriel Genellina schrieb:
> 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.
> 

> 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

intersting
I think I got it

[]

I have two more examples, but now I understand the difference

In [70]: x = [eval("lambda:i") for i in range(10)]
In [71]: y = [eval("lambda:%i" % i) for i in range(10)]

I think [71] is most obvious what the programmer intends

Thx



More information about the Python-list mailing list