2013-06-01 64 views
14

我知道,Python的`map`和參數拆包

map(function, arguments) 

相當於

for argument in arguments: 
    function(argument) 

是否可以使用地圖功能來執行以下操作?

for arg, kwargs in arguments: 
    function(arg, **kwargs) 
+1

這兩件事情都沒有當量。 'map()'建立函數調用返回值的列表(或3.x,一個生成器)。如果你不想使用這些值,不要使用'map()',只需使用正常的循環。 –

+5

map是一個函數(返回一個列表),循環是沒有返回值的代碼。它們不相同。 –

回答

16

您可以與拉姆達:

map(lambda a: function(a[0], **a[1]), arguments) 

,或者你可以用生成器表達式或列表的理解,這取決於你想要什麼:

(function(a, **k) for a, k in arguments) 
[function(a, **k) for a, k in arguments] 

在Python 2,map()返回一個列表(所以列表理解是等效的),在Python 3中,map()是一個生成器(因此生成器表達式可以替代它)。

沒有直接執行此操作的內置或標準庫方法;用例過於專業化。

0

你只需要記住,map將參數作爲一個元組傳遞給函數,而不是單獨的參數。如果你不能改變你原有的功能,你可以用一個輔助函數調用它:

def f(tup): 
    args, kwargs = tup 
    function(args, **kwargs) 

map(f, arguments) 
7

對於只有位置參數的情況下,你可以使用itertools.starmap(fun, args)

返回一個迭代器,其值從使用從給定序列中獲取的參數元組進行評估的函數返回。

例子:

from itertools import starmap 

def f(i, arg): 
    print(arg * (i+1)) 

for _ in starmap(f, enumerate(["a", "b", "c"])): 
    pass 

打印:

a 
bb 
ccc 
0

我一直運行到相同的需求,並最終作出了以下功能:

def kwarg_map(element_constructor, **kwarg_lists): 
    """ 
    A helper function for when you want to construct a chain of objects with individual arguments for each one. Can 
    be easier to read than a list expansion. 

    :param element_constructor: A function of the form object = fcn(**kwargs) 
    :param kwarg_lists: A dict of lists, where the index identifies two which element its corresponding value will go. 
    :return: A list of objects. 

    e.g. Initializing a chain of layers: 
     layer_sizes = [784, 240, 240, 10] 
     layers = kwarg_map(
      Layer, 
      n_in = layer_sizes[:-1], 
      n_out = layer_sizes[1:], 
      activation = ['tanh', 'tanh', 'softmax'], 
      ) 

    is equivalent to: 
     layers = [Layer(n_in=784, n_out=240, activation='tanh'), Layer(n_in=240, n_out=240, activation='tanh'), Layer(n_in=240, n_out=10, activation='softmax')] 
    """ 
    all_lens = [len(v) for v in kwarg_lists.values()] 
    assert len(kwarg_lists)>0, "You need to specify at least list of arguments (otherwise you don't need this function)" 
    n_elements = all_lens[0] 
    assert all(n_elements == le for le in all_lens), 'Inconsistent lengths: %s' % (all_lens,) 
    return [element_constructor(**{k: v[i] for k, v in kwarg_lists.iteritems()}) for i in xrange(n_elements)]