Python 如何忽略元组的未打包部分作为lambda参数?

Python 如何忽略元组的未打包部分作为lambda参数?,python,lambda,tuples,iterable-unpacking,argument-unpacking,Python,Lambda,Tuples,Iterable Unpacking,Argument Unpacking,在Python中,按照惯例,下划线()通常用于丢弃未打包元组的一部分,如下所示 >>> tup = (1,2,3) >>> meaningfulVariableName,_,_ = tup >>> meaningfulVariableName 1 我试图对lambda的元组参数做同样的处理。这似乎是不公平的,它只能与2元组 >>> map(lambda (meaningfulVariableName,_): meaning

在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)
>>映射(lambda(meaningfullvariablename,uu):meaningfullvariablename*2,[(1,10),(2,20),(3,30)])#这很好
[2, 4, 6]
>>>地图(lambda(meaningfullvariablename,u,u):meaningfullvariablename*2,[(1,10100),(2,20200),(3,30300)])#但我需要这个!
SyntaxError:函数定义(,第1行)中有重复的参数“\u1”

你知道为什么吗?实现这一点的最佳方法是什么?

元组在Python中是不可变的,所以你不能“丢弃”(修改)无关的值

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

我要做的是,在您感兴趣的索引处对元组进行索引,如下所示:

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

无需使用
*args
或伪变量。

您通常最好使用列表理解,而不是
lambda
s:

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

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

因为它在注释中,只需使用参数即可 要在“\u1”中抛出剩余参数,请执行以下操作:

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

from itertools import starmap
result = map(lambda x, *_: x, [(0,1,2),])
但是没有与
排序
排序
的关键参数等效的参数

如果你不在元组中间使用参数, 只需给这些编号:

lambda x, _1, _2, _3, w: x*2 + w
如果您收到一些linter工具关于未使用的参数的投诉:linter的目的是建议使用mor可读代码。我个人的偏好是不要让它妨碍实践,如果发生这种情况,我会毫不犹豫地关掉那行代码的门楣

否则,你真的必须做“漂亮”的事情——如果是为了取悦你和你的团队,或者仅仅是为了取悦门楣工人,那就用好的判断力。在这种情况下,需要编写一个完整的函数,并假装 使用未使用的参数

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
除了linter有问题外,其目的是使lambda参数可读,然后无论如何推荐使用一个成熟的函数<代码>lambda在v。3.0,以保证可读性

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

Namedtuple是一个很好的解决方案: 从集合导入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)

lambda x,*.\ux:2
lambda t:t[0]*2
取决于调用函数或
lambda(x,dummy1,dummy2):x*2
或只编写一个函数。在Python 3中,你根本不能在函数的参数列表中进行解包:无论什么语法都完全消失了。我不想改变元组。至于
x[0]
建议,其可读性不如
meaningfullvariablename
(参见更新的问题)@朱利安,事实上,因为你想对元组中的一个元素进行操作,而这个元素没有加星号(因此你将把整个元组作为lambda的参数),这是唯一的方法。@朱利安在PEP 8中没有提到如何操作,所以这取决于个人偏好。我个人认为高效、简洁的代码更具可读性,但并不是每个人都这么认为。谢谢,但我真正的应用程序(
sorted(mess,key=lambda…
)不能用列表理解来表达。@Julian你问题中给出的应用程序是
map(lambda…)
,这就是我写这个答案的原因。对于
sorted()<代码>未使用。*
应包含在默认配置中。(当然有更多的Python linter,但pylint是一个非常常见的)谢谢,但这并没有达到我的预期:
map(lambda meaningfullvariablename,*.\u:meaningfullvariablename*2,[(1,10100),(2,20200),(3,30300)]
是的,
排序
不会“星型”为您调用lambda-您确实需要创建一个显式函数,或者使用@ariOpenheimer的建议,只需选择lambda内部的元组索引即可。@Julian您在问题中用于lambda的“destructuring”语法已从Python中删除,因为它被认为太模糊,很少使用。应将其视为已弃用,且不在新代码中使用;无论如何,所有代码都必须很快迁移到Python 3。因此,对于
sorted()
中的键函数,只需编写一个适当的函数,并在该函数的第一行umpack元组。或者,使用
namedtuple
s,这样就可以使用
sorted(a,key=lambda x:(x.last\u name,x.first\u na
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)