混淆python星号表示法的双重用法(作为函数参数,或作为函数定义)

时间:2013-08-02 22:29:52

标签: python functional-programming

我有点困惑。让我们创建一个名为x的函数。我知道通过在*之前放*,这意味着我们可以添加任意数量的参数。

def x(*y):
    return y

然而。

案例1:

>>> x(1, 2)
(1, 2)

案例2: 让我们在它之前用星号传递一个列表[1,2]:

>>> x(*[1,2])
(1, 2)

单个星号似乎有两个用途:

  1. 允许函数中的多个参数 - 基本上将它们放入列表中
  2. 如果完成两次,将一个列表“拆分”为单独的项目
  3. 这是为什么?为什么我不能这样做:* a * b?

2 个答案:

答案 0 :(得分:3)

函数定义中的星号与函数调用中的星号完全分开。你不需要两颗星就可以将列表分成不同的参数:

def f(a, b, c):
    return a*b + c

f(*(1, 2, 3)) # returns 5

在定义中,带星号的参数接收任何不适合声明的位置参数的位置参数,包含在元组中。在一个调用中,Python迭代一个带星号的参数,并将这些元素作为参数单独传递。这些功能有时可以在一起使用,但很少会定义一个带有星号参数的函数,只是总是将它传递给一个带星号的参数。

答案 1 :(得分:3)

在函数定义中*用于收集元组中的所有位置参数,在函数调用中*解包迭代并将其作为位置参数传递。

如果通过*a*b你试图解包两个iterables / iterators ab,那么正确的方法是:

>>> a = [1, 2, 4]
>>> b = 'foo'
>>> from itertools import chain
def func(*x):
    print x
...     
>>> func(*chain(a,b)) #chain will work for both iterators and iterables
(1, 2, 4, 'f', 'o', 'o')

如果ab属于同一类型且可迭代,那么您也可以使用:

>>> a = [1, 2, 4]
>>> b = [0,1]
>>> func(*(a + b))
(1, 2, 4, 0, 1)