(译)Python’s lambda is broken!(Python的lambda坏了!)

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))








你可能感兴趣的:(python,F#,haskell)