Python3 在 lambda 表达式中不支持将迭代返回的 tuple 对象拆包为对应的参数吗?
例如:
map(lambda: i, x: (i + 1, x), enumerate(sys.argv))
上面这段代码在 Python3 中是错误的,必须改为
map(lambda: x: (x[0] + 1, x[1]), enumerate(sys.argv))
不可以将 tuple 或 list 对象可以自动拆包了,还是有别的方法呢?
Python3 在 lambda 表达式中不支持将迭代返回的 tuple 对象拆包为对应的参数吗?
lambda 后面多了个 :
是的,Python 3 的 lambda 表达式本身不支持像 def 函数那样使用 *args 或 (a, b) 的形式进行参数解包。比如,你想写 lambda (x, y): x + y 来直接处理元组,这在 Python 2 里可以,但在 Python 3 里会报语法错误。
不过,有几种常见的变通方法:
-
在 lambda 内部手动索引或解包:既然传给 lambda 的是一个元组,你可以在表达式里通过下标来访问。
# 假设有一个元组列表 pairs = [(1, 2), (3, 4), (5, 6)] # 方法1:通过索引 result = list(map(lambda t: t[0] + t[1], pairs)) # 方法2:在lambda内部解包 result = list(map(lambda t: (lambda x, y: x + y)(*t), pairs)) -
使用普通函数定义:如果逻辑稍微复杂,直接用
def定义函数会更清晰,它支持参数解包。def add_pair(x, y): return x + y result = list(map(add_pair, *zip(*pairs))) # 或者用其他方式应用更直接地,如果你在遍历一个元组列表,完全可以在循环里解包:
result = [x + y for x, y in pairs] -
结合
starmap(针对map场景):itertools.starmap就是专门为这种“将可迭代对象中的每个元素解包作为函数参数”设计的。from itertools import starmap result = list(starmap(lambda x, y: x + y, pairs))这是最接近你原来想法且代码简洁的方式。
总结:用 starmap 或内部解包来绕过限制。
等效语法:
((i + 1, x) for i, x in enumerate(sys.argv))
map 已经不推荐用了
嗯,手写的代码。
map 不能用了,那么 filter 怎么办呢?
直接用 list comprehension ?
[(x[0] + 1, x[1]) for x in enumerate(sys.argv)]这样?
from itertools import startmap
starmap(lambda i, x: (i + 1, x), enumerate(sys.argv))
typo: startmap -> starmap
Thank you, itertools.startmap 的确进行了拆包。
#5 就是 2L 那样, 2L 的结果是一个 Generator ,最外面的圆括号换成方括号结果就是列表。
不好意思打错了
map(lambda i, x: (i + 1, x), *zip(*enumerate(sys.argv)))
Lambda i, x 这样是接受两个 argument , tuple 是一个,可以用星号*展开成两个
也可以这样定义 lambda (i, x),这样就是接受一个 tuple
就算是普通函数也不能自动拆包啊,而要用*显式展开。因为函数根本不知道需不需要拆包,假如你就是想传入一个类型是 tuple 的参数呢。


