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

本文通过一个具体的例子揭示了Python中使用lambda表达式时容易遇到的问题,即闭包捕获变量的实际行为与预期不符的情况,并提供了几种解决该问题的有效方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[url]http://math.andrej.com/2009/04/09/pythons-lambda-is-broken/[/url]


[size=medium][align=center]Python"s lambda is broken![/align][/size]
[size=medium][align=center]Python的lambda坏了![/align][/size]

我很喜欢用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))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值