在 lambda 中自动元组解包的好的 python3 等价物是什么? [英] What is the good python3 equivalent for auto tuple unpacking in lambda?

查看:53
本文介绍了在 lambda 中自动元组解包的好的 python3 等价物是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑下面的python2代码

在[5]中:points = [ (1,2), (2,3)]在 [6] 中: min(points, key=lambda (x, y): (x*x + y*y))输出[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返回 x*x + y*y

在python3中删除这个特性迫使代码要么做丑陋的方式(使用魔术索引)要么创建不必要的函数(最麻烦的部分是为这些不必要的函数想个好名字)

我认为该功能至少应该单独添加到 lambdas 中.有没有好的选择?

<小时>

更新:我正在使用以下助手扩展答案中的想法

def star(f):返回 lambda 参数:f(*args)min(points, key=star(lambda x,y: (x*x + y*y))

<小时>

Update2:star

的更简洁版本

import functools定义星(f):@functools.wraps(f):def f_inner(args):返回 f(*args)返回 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]>>>一个((3,4))25

应该记住,这种代码很少会比拥有完整功能更具可读性或实用性.尽管如此,还是有可能的用途——如果有各种单行程序可以在这个 point 上进行操作,那么拥有一个命名元组并使用赋值表达式来有效地转换"传入序列可能是值得的到命名元组:

<预><代码>>>>从集合导入namedtuple>>>point = namedtuple("point", "x y")>>>b = lambda s: (p:=point(*s), p.x ** 2 + p.y ** 2)[-1]

Consider the following python2 code

In [5]: points = [ (1,2), (2,3)]

In [6]: min(points, key=lambda (x, y): (x*x + y*y))
Out[6]: (1, 2)

This is not supported in python3 and I have to do the following:

>>> min(points, key=lambda p: p[0]*p[0] + p[1]*p[1])
(1, 2)

This is very ugly. If the lambda was a function, I could do

def some_name_to_think_of(p):
  x, y = p
  return x*x + y*y

Removing this feature in python3 forces the code to either do the ugly way(with magic indexes) or create unnecessary functions(The most bothering part is to think of good names for these unnecessary functions)

I think the feature should be added back at least to lambdas alone. Is there a good alternative?


Update: I am using the following helper extending the idea in the answer

def star(f):
  return lambda args: f(*args)

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


Update2: A cleaner version for star

import functools

def star(f):
    @functools.wraps(f):
    def f_inner(args):
        return f(*args)
    return f_inner

解决方案

No, there is no other way. You covered it all. The way to go would be to raise this issue on the Python ideas mailing list, but be prepared to argue a lot over there to gain some traction.

Actually, just not to say "there is no way out", a third way could be to implement one more level of lambda calling just to unfold the parameters - but that would be at once more inefficient and harder to read than your two suggestions:

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

update Python 3.8

As of now, Python 3.8 alpha1 is available, and PEP 572- assignment expressions are implemented.

So, if one uses a trick to execute multiple expressions inside a lambda - I usually do that by creating a tuple and just returning the last component of it, it is possible to do:

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

One should keep in mind that this kind of code will seldom be more readable or practical than having a full function. Still, there are possible uses - if there are various one-liners that would operate on this point, it could be worth to have a namedtuple, and use the assignment expression to effectively "cast" the incoming sequence to the namedtuple:

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

这篇关于在 lambda 中自动元组解包的好的 python3 等价物是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆