在lambda中自动元组解包的python3等效项是什么?

发布于 2021-01-29 15:04:13

考虑以下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
关注者
0
被浏览
110
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    不,没有其他办法。您覆盖了所有内容。可行的方法是在Python想法邮件列表中提出此问题,但要准备在那儿争论很多以获得更多关注。

    实际上,只是不说“没有出路”,第三种方法可能是实现一个更高级别的lambda调用,只是为了展开参数-但这将比您的两个建议效率更高,更难以阅读:

    min(points, key=lambda p: (lambda x,y: (x*x + y*y))(*p))
    

    更新Python 3.8

    到目前为止,Python 3.8 alpha1已可用,并且已实现PEP 572赋值表达式。

    因此,如果使用技巧在lambda内执行多个表达式-我通常通过创建一个元组并仅返回它的最后一个组件来做到这一点,可以这样做:

    >>> a = lambda p:(x:=p[0], y:=p[1], x ** 2 + y ** 2)[-1]
    >>> a((3,4))
    25
    

    应该记住,与具有完整功能相比,这种代码很少会更具可读性或实用性。仍然有可能的用途-
    如果有各种各样的单行代码可以对此进行操作point,则值得拥有一个namedtuple,并使用赋值表达式将输入序列有效地“投射”到namedtuple:

    >>> from collections import namedtuple
    >>> point = namedtuple("point", "x y")
    >>> b = lambda s: (p:=point(*s), p.x ** 2 + p.y ** 2)[-1]
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看