5

在 Python 中,按照惯例,下划线 ( _) 通常用于丢弃未打包元组的一部分,如下所示

>>> tup = (1,2,3)
>>> meaningfulVariableName,_,_ = tup
>>> meaningfulVariableName
1

我正在尝试对 lambda 的元组参数做同样的事情。只能用 2 元组来完成,这似乎是不公平的......

>>> map(lambda (meaningfulVariableName,_): meaningfulVariableName*2, [(1,10), (2,20), (3,30)]) # This is fine
[2, 4, 6]

>>> map(lambda (meaningfulVariableName,_,_): meaningfulVariableName*2, [(1,10,100), (2,20,200), (3,30,300)]) # But I need this!
SyntaxError: duplicate argument '_' in function definition (<pyshell#24>, line 1)

任何想法为什么,以及实现这一目标的最佳方法是什么?

4

3 回答 3

4

就像在评论中一样,只需使用凝视的参数在“_”中抛出剩余的参数:

lambda x, *_: x*2 

如果您在map语句中使用这些,因为 Python 不会将元组中的每个项目映射到不同的参数,您可以使用itertools.starmap,这样做:

from itertools import starmap
result = map(lambda x, *_: x, [(0,1,2),])

sort但是在or的关键参数上没有等价物sorted

如果您不会在元组中间使用参数,只需编号:

lambda x, _1, _2, _3, w: x*2 + w

如果您从一些 linter 工具收到关于未使用参数的投诉:linter 的目的是建议更易读的代码。我个人的偏好是不要让它妨碍实践,如果发生这种情况,我会不加思索地关闭那行代码的 linter。

否则,你真的必须做“漂亮”的事情——如果是为了取悦你和你的团队,或者只是为了取悦 linter,请使用理智。在这种情况下,它是编写一个完整的函数,并假装消耗未使用的参数。

def my_otherwise_lambda(x, unused_1, unused_2, w):
     """My make linter-happy docstring here"""
     unused_1, unused_2  # Use the unused variables
     return 2 * x + w

短绒没有问题,目的是让 lambda 参数可读,然后推荐一个完整的函数。lambda为了保证可读性,在 v. 3.0 中真的很接近被剥夺语言。

最后但并非最不重要的一点是,如果元组中值的语义如此有意义,也许您应该考虑使用一个类来保存其中的值。这样,您可以将该类的实例传递给 lambda 函数并通过它们各自的名称检查值。

Namedtuple 是一种很好用的方法: from collections import namedtuple

vector = namedtuple("vector", "x y z")

mydata = [(1,10,100), (2,20,200), (3,30,300)]
mydata = [vector(*v) for v in mydata]

sorted_data = sorted(mydata, lambda v: v.x * 2)
于 2017-12-05T13:58:13.510 回答
1

元组在 Python 中是不可变的,因此您将无法“丢弃”(修改)无关值。

此外,由于您不关心这些值是什么,因此绝对没有必要将它们分配给变量。

我要做的是简单地在您感兴趣的索引处索引元组,如下所示:

>>> list(map(lambda x: x[0] * 2, [(1,10,100), (2,20,200), (3,30,300)]))
[2, 4, 6]

不需要*args或虚拟变量。

于 2017-12-04T22:57:31.493 回答
1

你通常最好使用列表推导而不是lambdas:

some_list = [(1, 10, 100), (2, 20, 200), (3, 30, 300)]
processed_list = [2 * x for x, dummy1, dummy2 in some_list]

如果你真的坚持,你可以在这里使用_而不是dummy1dummy2。但是,我建议不要这样做,因为我经常看到这会引起混乱。人们通常认为_是某种特殊的语法(例如在 Haskell 和 Rust 中),而它只是一些不寻常的变量名,没有任何特殊属性。这种混淆完全可以通过使用像dummy1. 此外,_它与常见的 gettext 别名冲突,并且它在交互式解释器中也确实具有特殊含义,因此总体而言我更喜欢使用dummy以避免所有混淆。

于 2017-12-04T23:07:18.947 回答