当前位置: 首页 > 面试题库 >

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

壤驷雅达
2023-03-14
问题内容

考虑以下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

问题答案:

不,没有其他办法。您覆盖了所有内容。可行的方法是在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]


 类似资料:
  • 问题内容: 有Swift的等效项吗?在中,我们通常使用: 如何在Swift中实现相同目标?我发现了一个功能: 但是,它很长,根本不方便。 问题答案: 将在斯威夫特的世界同样存在。 的,和参数均标有 该装置的同时调用该函数我们可以忽略这些参数的关键字。在这种情况下,将使用其默认值。 这得出一个结论,该方法调用可以简化为: Swift 5- 没什么变化,仍然可以这样工作。

  • 问题内容: 在TSQL中,我可以声明: 在MySQL中,我无法编写相同的查询。 在MySQL中编写此查询的正确方法是什么? 问题答案: 行尾的分号。

  • 问题内容: LINQ的Java等效项是什么? 问题答案: 现在使用Java 8向我们介绍了Stream API,这在处理集合时是类似的事情,但与Linq不太一样。 如果它是您正在寻找的ORM,例如Entity Framework,那么您可以尝试Hibernate

  • 问题内容: 我有以下代码,该代码将字符串作为输入,并转换为UNIX时间戳。我想在golang中做同样的事情,但我无法识别将在Go中提供等效于DateTimeOffset结构的结构或函数。 例如: 输入:635804753769100000 输出:1444878577 UTC对应时间:10/15/2015 3:09:36 AM +00:00 有人可以帮我解决这个问题,以获得上述结果。 谢谢 问题答案

  • 问题内容: Golang中C ++的等效功能是什么? 根据这里的问题,我可以得到以下声明: 但这将导入整个名称空间。现在我只想使用诸如定义之类的东西 Go中有与此等效的功能,因此我不必一直输入吗? 问题答案: 以下代码在可读性方面接近,但效率较低,因为编译器无法再内联函数调用。 而且,它具有输入名称的副作用,并到该文件的范围,这恐怕是C ++的没有做。

  • 我偶然发现以下Java代码使用了的方法引用: 的等效lambda表达式是什么?