考虑以下 python2 代码
In [5]: points = [ (1,2), (2,3)]
In [6]: min(points, key=lambda (x, y): (x*x + y*y))
Out[6]: (1, 2)
这在 python3 中不受支持,我必须执行以下操作:
>>> min(points, key=lambda p: p[0]*p[0] + p[1]*p[1])
(1, 2)
这非常丑陋。如果 lambda 是一个函数,我可以做
def some_name_to_think_of(p):
x, y = p
return x*x + y*y
在 python3 中删除此功能会强制代码以丑陋的方式(使用魔术索引)或创建不必要的函数(最麻烦的部分是为这些不必要的函数想出好名字)
我认为该功能至少应该单独添加回 lambda。有好的选择吗?
更新: 我正在使用以下助手扩展答案中的想法
def star(f):
return lambda args: f(*args)
min(points, key=star(lambda x,y: (x*x + y*y))
Update2: 更清洁的版本 star
import functools
def star(f):
@functools.wraps(f)
def f_inner(args):
return f(*args)
return f_inner
原文由 balki 发布,翻译遵循 CC BY-SA 4.0 许可协议
不,没有别的办法。你涵盖了这一切。要走的路是在 Python 思想邮件列表 上提出这个问题,但要准备好在那里争论很多以获得一些牵引力。
实际上,只是不要说“没有出路”,第三种方法可能是实施更多级别的 lambda 调用只是为了展开参数 - 但这会比你的两个建议更加低效和难以阅读:
Python 3.8 更新
自 Python 3.8 发布以来,PEP 572(赋值表达式)已作为一种工具提供。
所以,如果有人使用技巧在 lambda 中执行多个表达式——我通常通过创建一个元组并只返回它的最后一个组件来做到这一点,可以执行以下操作:
应该记住,这种代码很少会比具有完整功能的代码更具可读性或实用性。尽管如此,还是有可能的用途——如果有各种单行代码可以在这个
point
上运行,那么值得拥有一个namedtuple
,并使用赋值表达式有效地“将传入序列“投射”到命名元组: