我在档案中找不到这样的问题。
使用for
可以解包迭代对:
>>> for i, x in enumerate([5,10,15]): print('x[%d]=%d' % (i, x))
x[0]=5
x[1]=10
x[2]=15
或也可以不 解包:
>>> for x in enumerate([5,10,15]): print(x)
(0, 5)
(1, 10)
(2, 15)
但是,使用map()
时,此解包是不可能的:
>>> list(map(lambda i, x: x**i, enumerate([5,10,15])))
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: <lambda>() missing 1 required positional argument: 'x'
这是为什么?设计选择?为什么?
我想可以实现这样的包装器:
def map1(func, *iterables):
from inspect import signature
params = signature(func).parameters
if len(params) == 1:
yield from map(func, *iterables)
else:
yield from map(lambda x: func(*x), *iterables)
(适用于所有情况)
或另一个,盲目解包参数:
def map2(func, *iterables):
yield from map(lambda x: func(*x), *iterables)
(我猜后者会造成一些麻烦)
有没有(好)理由不这样做?
答案 0 :(得分:4)
这不是$this->db->trans_off()
的问题,而是问lambda
。 documentation说:
如果传递了其他可迭代参数,则函数必须使用那么多参数,并且并行地应用于所有迭代中的项。
换句话说,函数必须使用与您传递的可迭代次数相同数量的参数。迭代中每个单独元素的大小无关紧要。
如果要将单个 iterable的每个元素作为多个参数传递,可以使用map
和参数解包来转置序列:
zip
正如Ashwini所说,您也可以使用itertools.starmap
代替>>> map(lambda i, x: x**i, *zip(*enumerate([5,10,15])))
[1, 10, 225]
。
答案 1 :(得分:1)
这是因为enumerate()
返回一个枚举对象,该对象在多个枚举对象中保存一对值。如果您尝试:
>>> enumerate([5,10,15])
>>> <enumerate at 0x39152d8>
>>>e = enumerate([5,10,15])
>>> for i in e:
print e
<enumerate object at 0x03915080>
<enumerate object at 0x03915080>
<enumerate object at 0x03915080>
你在声明中做了什么:
map(lambda i, x: x**i, enumerate([5,10,15]))
将return
的{{1}}值传递给enumerate()
。因此,当您指定两个参数时,它只获得一个值。
如果您尝试:
lambda
你得到预期的输出