请教lambda问题:

请教lambda问题:

请教lambda问题:
>>> a=[lambda ar:ar*i for i in range(co)]
>>> for t in range(co):
...          a[t](2)
...
14
14
14
14
14
14
14
14
>>> >>>

结果为什么不是
0
2
4
6
8
10
12
14
呢?
我算的结果, 似乎没什么问题啊?

co=8

a = [lambda ar: ar*i for i in range(co)]

for i in range(co):
    print a[i](2)

0
2
4
6
8
10
12
14


[Copy to clipboard] [ - ]
CODE:
r = range(8)
a = [lambda ar: ar*i for i in r]
print 'use var i ------------------------'
for i in r:
        print i, type(i), a[i](2)
print 'use var j ------------------------'
for j in r:
        print j, type(j), a[j](2)

结果
use var i ------------------------
0 <type 'int'> 0
1 <type 'int'> 2
2 <type 'int'> 4
3 <type 'int'> 6
4 <type 'int'> 8
5 <type 'int'> 10
6 <type 'int'> 12
7 <type 'int'> 14
use var j ------------------------
0 <type 'int'> 14
1 <type 'int'> 14
2 <type 'int'> 14
3 <type 'int'> 14
4 <type 'int'> 14
5 <type 'int'> 14
6 <type 'int'> 14
7 <type 'int'> 14
看来 lambda ar: ar*i 这种使用了没有定义的参数,是在运行时去找同名的变量。
并且 lambda ar: ar*i 里面的 i 也不是 for i in r 里面的那个 i

我想这个问题可能是这样的。lamdba是先定义的,它的定义形式是:

lambda ar: ar*i

而不是象想象的i变成实际的值,因此 上面得到的a数组都是相同的函数,而不是有所不同。因此在使用i进行循环时,正好i的值从0-7,但这样得到的函数却仍然使用的是i,而不是具体的值。虽然for语句计算的结果正好与想象得一样,这是因为i正好又从0-7。在改为j时,i的最后一个值是7,所以得到的永远是14。可以通过这样来验证:

在定义完a之后,打印i看一看。

可以考虑把函数定义设定一个关键字参数:

[Copy to clipboard] [ - ]
CODE:
a = [lambda ar,a=i: ar*a for i in r]

通过a进行传入,这样a就会保留缺省值i了。


QUOTE:
原帖由 limodou 于 2006-6-7 09:39 发表
我想这个问题可能是这样的。lamdba是先定义的,它的定义形式是:

lambda ar: ar*i

而不是象想象的i变成实际的值,因此 上面得到的a数组都是相同的函数,而不是有所不同。因此在使用i进行循环时,正好i的值从 ...

这下明白了