http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/
Python"s lambda is broken!
Python的lambda坏了!
我很喜欢用Python来教学,并且人们赞美lambda的够造—它像一个抽象的函数式语言,但是,它有时出错!
来看看lambda是怎么出错的把,构造一个list,list里包含函数`fs = [f_0, ..., f_9]` ,并且我们想让函数是这样的`f_i(n) = i + n`。一开始我们试图这样写:
>>> fs = [(lambda n: i + n) for i in range(10)]
>>> fs[3](4)
13
等一下,f[3](4)应该是3+4 = 7!这看起来像10个函数用了一个最后一个i的值---9,事实上
>>> [f(4) for f in fs]
[13, 13, 13, 13, 13, 13, 13, 13, 13, 13]
这肯定不对,让我们不用lambda试试:
>>> fs = []
>>> for i in range(10):
... def f(n): return i+n
... fs.append(f)
...
>>> [f(4) for f in fs]
[13, 13, 13, 13, 13, 13, 13, 13, 13, 13]
它仍然不对,深想一下,可能是环境不对,可能应该这样:
>>> fs = []
>>> for i in range(10):
... def f(n, i=i): return i+n
... fs.append(f)
...
>>> [f(4) for f in fs]
[4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
胜利!但是我试图想学生们解释这是为什么。
只是很确定地,Haskell却能够实现
Prelude> let fs = [(\n -> i + n) | i <- [0..9]]
Prelude> [f(4) | f <- fs]
[4,5,6,7,8,9,10,11,12,13]
Python的解释器在想什么?!
楼下mcmanus给出了个很好的解释:
>>> i = 1
>>> def f(): return i
>>> f()
1
>>> i = 2
>>> f()
2
楼下roberto又给出了个解决方案:
>>> fs = [(lambda n, i=i: i + n) for i in range(10)]
楼下tim finin的方法
>>> def def_f(i):
return lambda n: i + n
>>> fs = [def_f(i) for i in range(10)]
>>> fs[3](4)
7
Kamran的
fs= map(lambda i:lambda n: i + n, range(10))