why is this different?

  • Thread starter =?ISO-8859-1?Q?Sch=FCle_Daniel?=
  • Start date
?

=?ISO-8859-1?Q?Sch=FCle_Daniel?=

Hello snakes :)

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
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']


doing it like this works again

In [54]: def d(x):
....: return lambda:x
....:

In [55]: f = [d(i) for i in range(10)]
In [56]: f[0]()
Out[56]: 0
In [57]: f[1]()
Out[57]: 1

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

Regards, Daniel
 
?

=?ISO-8859-1?Q?Sch=FCle_Daniel?=

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

Gabriel Genellina

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
( said:
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:
( said:
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.
 
M

Marc 'BlackJack' Rintsch

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

But unnecessary use of `eval()` is evil. You can spell it this way:

z = [lambda x=i: x for i in range(10)]

The `x` is a local name and default values are evaluated and bound when
the function is created.

Ciao,
Marc 'BlackJack' Rintsch
 
G

Gabriel Genellina

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
( said:
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:
( said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,161
Latest member
GertrudeMa
Top