简体   繁体   English

使用map()时使用* idiom解包参数

[英]Using * idiom to unpack arguments when using map()

Is there a way to unpack a tuple with the * idiom when using the map built-in in Python? 有没有办法在使用Python内置的map时用*惯用法解包元组?

Ideally, I'd like to do the following: 理想情况下,我想做以下事情:

def foo(a, b):
  return a**2 + b

x = [(1,2), (3,4), (5,6)]

results = map(foo, *x)

where results would equal [3, 13, 31] 结果相等[3, 13, 31]

You're looking for itertools.starmap : 您正在寻找itertools.starmap

def foo(a, b):
  return a**2 + b

x = [(1,2), (3,4), (5,6)]

from itertools import starmap

starmap(foo, x)
Out[3]: <itertools.starmap at 0x7f40a8c99310>

list(starmap(foo, x))
Out[4]: [3, 13, 31]

Note that even in python 2, starmap returns an iterable that you have to manually consume with something like list . 请注意,即使在python 2中, starmap返回一个必须使用list类的手动使用的iterable。

An uglier way than the @roippi's way... 比@ roippi的方式更丑陋......

x = [(1,2), (3,4), (5,6)]

map(lambda y:y[0]**2 + y[1], x)

As it happens, map accepts *args, so your original call map(foo, *x) doesn't immediately fail - but what happens is that each element from x is treated as a sequence of values for one argument to foo - so it attempts foo(1, 3, 5) and would then attempt foo(2, 4, 6) except of course that foo only accepts 2 arguments. 碰巧, map接受* args,所以你的原始调用map(foo, *x)不会立即失败 - 但是会发生的事情是x中的每个元素都被视为foo一个参数的值序列 - 所以它尝试foo(1, 3, 5) ,然后尝试foo(2, 4, 6) ,当然foo只接受2个参数。

Since we can see that our input x is effectively the "matrix transpose" of what we would like to feed in, that directly points us to a workaround: 由于我们可以看到输入x实际上是我们想要提供的“矩阵转置”,这直接指出了我们的解决方法:

>>> list(map(foo, *zip(*x))) # list() wrapping for 3.x support
[3, 13, 31]

... But don't do that. ......但不要这样做。 Use itertools.starmap ; 使用itertools.starmap ; it's built for this and considerably clearer about your intent. 它是为此而构建的,并且相当清楚您的意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM