【问题标题】:How to use a map with *args to unpack a tuple in a python function call如何使用带有 *args 的映射在 python 函数调用中解包元组
【发布时间】:2014-03-29 22:53:06
【问题描述】:

我目前正在对一组我想要并行化的变量进行合并。我的代码如下所示:

mergelist = [
  ('leftfile1', 'rightfile1', 'leftvarname1', 'outputname1'),
  ('leftfile1', 'rightfile1', 'leftvarname2', 'outputname2')
  ('leftfile2', 'rightfile2', 'leftvarname3', 'outputname3')
]

def merger(leftfile,rightfile,leftvarname,outvarname):
   do_the_merge

for m in mergelist:
     merger(*m)

通常,为了加快长循环,我会将 for m in mergelist 替换为...。

from multiprocessing import Pool

p = Pool(8)
p.map(merger(m), mergelist)
p.close()

但由于我使用星号来解包元组,我不清楚如何正确映射它。如何获得*m

【问题讨论】:

  • itertools.starmap 的存在似乎意味着标准的map 不能轻易被强制执行此操作。当然,您可以创建一个包装函数,将唯一的参数解包后转发到实际实现。
  • 你如何定义merger?您不能将字符串文字指定为函数定义中的形式参数名称。
  • 谢谢chepner,我更正了;粗心的伪编码。我需要一个更好的伪代码解释器。 ;)

标签: python map functional-programming multiprocessing


【解决方案1】:

使用lambda:

with Pool(8) as p:
    p.map(lambda m:merger(*m), mergelist)

【讨论】:

  • 同样的想法,但更简单,更少打字。一个更好的解决方案。
  • 我稍微修改了我对 lambda 的喜爱。我很确定这不能分发,因为无法腌制 lambda:PicklingError: Can't pickle : attribute lookup builtin.function failed
【解决方案2】:

恕我直言,最简单的解决方案是更改合并功能,或添加包装器:

def merger(leftfile,rightfile,'leftvarname','outvarname'):
    do_the_merge

def merger_wrapper(wrapper_tuple):
    merger(*wrapper_tuple)

p.map(merger_wrapper, mergelist)

我看到@delnan 实际上也将这个解决方案放在了 cmets 中。

为了增加一点价值:)你也可以这样包装它:

from functools import partial
def unpack_wrapper(f):
    def unpack(arg):
        return f(*arg)
    return unpack

这应该可以让您将其简化为

p.map(unpack_wrapper(merger), mergelist)

【讨论】:

【解决方案3】:

您可以在合并函数中解压元组:

def merger(args):
    if len(args) != 4:
         # error
    leftfile,rightfile,leftvarname,outvarname = args
    do_the_merge

另一种选择是在参数列表中解包:

def merger( (leftfile,rightfile,leftvarname,outvarname) ):
    do_the_merge

编辑:解决 OP 问题:

def merger((l,r,v,o)):
    return l+r

for m in mergelist:
         print merger(m)

返回

leftfile1rightfile1
leftfile1rightfile1
leftfile2rightfile2

【讨论】:

  • 我不知道你能做到这一点(在参数列表中解压缩)。很酷。
  • 在参数列表中解包似乎不起作用。它拒绝了我的迭代。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-15
  • 1970-01-01
  • 2011-10-24
  • 1970-01-01
  • 1970-01-01
  • 2018-02-12
相关资源
最近更新 更多