Python lambda作为常量仿函数

时间:2014-07-11 09:24:26

标签: python lambda

我有labdas的代码,我每次创建函数对象时都检查过它是不同的(不是对同一个对象的引用), 但它没有像我期望的那样工作。有没有办法如何或者我应该使用仿函数来做它,即使我有插入lambda体内的常数数据?

pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')]

pairLambs = []

for p in pairs:
    pairLambs.append(lambda: print(p))

pairLambs[0]()
pairLambs[1]()
pairLambs[2]()

输出:

('abc', '987')
('abc', '987')
('abc', '987')

但我需要:

('abc', 'xyz')
('123', '987')
('abc', '987')

3 个答案:

答案 0 :(得分:10)

这是一个众所周知的问题 - 因为在定义p时你没有绑定lambda的当前值,所以在调用它时会使用当前值p。解决方案是使用带有默认值的命名arg来绑定p的“当前”(定义时间)值:

pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')]

pairLambs = []

for p in pairs:
    pairLambs.append(lambda p=p: print(p))

pairLambs[0]()
pairLambs[1]()
pairLambs[2]()

答案 1 :(得分:2)

如果您想专业化'功能,你应该看看functools

import functools

pairs = [('abc', 'xyz'), ('123', '987'), ('abc', '987')]
pairLambs = []
for p in pairs:
    pairLambs.append(functools.partial(print, p))

这会得到您期望的结果。

答案 2 :(得分:1)

这就是python中的闭包工作方式。要达到你想要的效果,你可以这样做:

 for p in pairs:
     def closure(_p):
         return lambda: print(_p)
     pairLambs.append(closure(p))