什么是在lambda自动元组解压缩好的python3等价物?
考虑下面的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中删除这个特性迫使代码以丑陋的方式(用神奇的索引)或者创build不必要的函数(最麻烦的部分是为这些不必要的函数考虑好名字)
我认为这个function至less应该添加到lambdaexpression式中。 有一个很好的select吗?
更新:我正在使用下面的助手在答案中延伸的想法
def star(f): return lambda args: f(*args) min(points, key=star(lambda x,y: (x*x + y*y))
不,没有别的办法。 你覆盖了这一切。 要走的路将是在Python的思路邮件列表中提出这个问题,但要准备在那里争论很多,以获得一些牵引力。
其实,只是不要说“没有出路”,第三种方法可能是实现一个lambda调用的更多层次来展开参数 – 但是这会比你的两个build议更加低效和难以阅读:
min(points, key=lambda p: (lambda x,y: (x*x + y*y))(*p))
根据http://www.python.org/dev/peps/pep-3113/ tuple解包不见了, 2to3
会像这样翻译它们:
由于lambdaexpression式由于单个expression式的限制而使用元组参数,所以它们也必须被支持。 这是通过将期望的序列参数绑定到单个参数,然后对该参数build立索引来完成的:
lambda (x, y): x + y
将被翻译成:
lambda x_y: x_y[0] + x_y[1]
这与您的实施非常相似。
我不知道任何Python 2参数解包行为的一般替代scheme。 以下是一些在某些情况下可能有用的build议:
-
如果你不能想到一个名字, 使用关键字参数的名称:
def key(p): # more specific name would be better x, y = p return x**2 + y**3 result = min(points, key=key)
-
如果列表在多个位置使用,则可以看到
namedtuple
使您的代码更具可读性:from collections import namedtuple from itertools import starmap points = [ (1,2), (2,3)] Point = namedtuple('Point', 'x y') points = list(starmap(Point, points)) result = min(points, key=lambda p: px**2 + py**3)
基于Cuadue的build议和你对解包的评论仍然存在于理解中,你可以使用numpy.argmin
:
result = points[numpy.argmin(x*x + y*y for x, y in points)]