解压缩多个列表作为函数的参数

Ant*_*lix 20 python

如果我有这样的功能:

def f(a,b,c,d):
    print a,b,c,d
Run Code Online (Sandbox Code Playgroud)

那么为什么会这样:

f(1,2,3,4)
f(*[1,2,3,4])
Run Code Online (Sandbox Code Playgroud)

但不是这个:

f(*[1,2] , *[3,4])
    f(*[1,2] , *[3,4])
               ^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)

编辑:有关信息,最初的问题是替换函数包装器中的一个参数.我想替换输入的*args的给定成员并尝试类似于:

def vectorize_pos(f,n=0):
    '''
    Decorator, vectorize the processing of the nth argument
    :param f: function that dont accept a list as nth argument
    '''
    def vectorizedFunction(*args,**kwargs):
        if isinstance(args[n],list):
            return map(lambda x : f( *(args[:n]) , x , *(args[n+1,:]), **kwargs),args[n])
        else:
            return f(*args,**kwargs)
    return vectorizedFunction
Run Code Online (Sandbox Code Playgroud)

这就是问题产生的地方.而且我知道还有其他方法可以做同样的事情,但只想了解为什么解压缩一个序列工作但不是更多.

the*_*eye 19

因为,根据Function调用语法,这是定义参数列表的方式

argument_list ::=  positional_arguments ["," keyword_arguments]
                     ["," "*" expression] ["," keyword_arguments]
                     ["," "**" expression]
                   | keyword_arguments ["," "*" expression]
                     ["," keyword_arguments] ["," "**" expression]
                   | "*" expression ["," keyword_arguments] ["," "**" expression]
                   | "**" expression
Run Code Online (Sandbox Code Playgroud)

因此,* expression每个函数调用只能传递一个.

  • 令人惊讶的是,像f(5,*[1],c = 3,**{'d':5})`这样令人讨厌的东西确实有效.我不知道,我一直认为你必须把'*`和`**`伪参数写在彼此旁边. (4认同)

ger*_*rit 13

从Python 3.5开始,这 确实 有效.

PEP 448在Python 3.5中实现.引用PEP,它允许,除其他外:

任意定位拆包运营商:

>>> print(*[1], *[2], 3)
1 2 3
>>> dict(**{'x': 1}, y=2, **{'z': 3})
{'x': 1, 'y': 2, 'z': 3}
Run Code Online (Sandbox Code Playgroud)


ndp*_*dpu 5

您可以连接列表:

>>> f(*[1,2]+[3,4])
1 2 3 4
Run Code Online (Sandbox Code Playgroud)

或使用itertools.chain:

>>> from itertools import chain
>>> f(*chain([1,2], [3,4]))
1 2 3 4
Run Code Online (Sandbox Code Playgroud)

  • 他的问题是为什么它不起作用.虽然你回答_how_使它工作.为此+1. (4认同)

Guy*_*Guy 5

起作用.

>>>def f(a,b,c,d):
         print('hello') #or whatever you wanna do. 
>>>f(1,2,*[3,4])
hello
Run Code Online (Sandbox Code Playgroud)

不起作用的原因是Python使用它来实现

一个列表解包,并且遵循语义,之后的任何参数必须是命名关键字参数(或通过**传递命名关键字参数的dictonary)

通过对比,这将起作用.

>>>def f(a,b,c,k):
       pass
>>>f(1,*[2,3],k=4)
Run Code Online (Sandbox Code Playgroud)