当作为参数传递给具有可变参数的函数时,列表解包如何工作?

时间:2015-02-11 20:51:44

标签: python list variables arguments

我有一个计算变量参数列表的算术平均值的函数。它有一个位置参数和rest变量参数。所以代码如下所示。

def mean(x, *l):
  sum = x
  for i in l:
     sum += i
  return sum / (1.0 + len(l))

现在我定义一个包含var参数的列表

z = [1,2,3,4]

现在我调用我的函数

mean(*z) which prints 2.5 which is correct.

那么这里发生了什么?我的理解是当我做* z它解压缩列表z。 但接下来它是如何从列表中选择第一个位置参数并保持列表的其余部分保持不变以获得“' l”的长度。如函数中所定义的那样。它是否解压缩列表z只是从z中提取第一个元素然后保留z的其余部分?如果可以用列表完成那么如何?

此外,如果我将z单独作为参数调用该函数,则会抛出错误

ari_mean(z)的 Traceback(最近一次调用最后一次):   文件"",第1行,in   文件"",第5行,在ari_mean中 TypeError:/:' list'不支持的操作数类型并且'浮动'

感谢。

2 个答案:

答案 0 :(得分:5)

当你打电话给mean(*z)时,你正确的是Python解包z,这意味着你的函数调用是等效的(在这种情况下),调用mean(1, 2, 3, 4)

现在,问题的第二部分:

  

解压缩列表z只是为了从z中提取第一个元素然后保留z的其余部分吗?

不是真的。首先,z被解压缩,每个参数分别传入(如上所述)。所以现在我们来看看均值的定义:def mean(x, *l):。这个定义期望至少有一个位置参数(x),而不是任意数量的额外参数。因此,由于您mean(*z)的初始调用已变为mean(1, 2, 3, 4),因此在meanx等于1*l成为(2, 3, 4)元组mean(z)

  

此外,如果我将z单独作为参数调用该函数,则会抛出错误

如果您只使用z单独调用该函数(x),那么,返回到您的函数定义,[1,2,3,4]将是列表ll将会是一个空元组。因为return sum / (1.0 + len(l))是一个空元组,所以在for循环中没有任何反应,你到达最后一行x。现在,因为[1,2,3,4] / 1.0是一个列表,Python会引发异常,因为它不知道如何计算{{1}}

答案 1 :(得分:0)

运行下面的代码可以向您展示其工作方式,注释显示了参数在函数中传递的方式。

def mean(x, *l):
    sum=x
    print("x:",x)
    print("l:",l)
    print("len(l):",len(l))
    for i in l:
        sum += i
    return sum / (1.0+len(l))

z = [1,2,3,4]
print("1st call:")
print("result:",mean(*z))  ##x = z[0] and l=tuple(z[1:])
print("\n\n2nd call:")
print("result:",mean(z))  ##x = z and l = tuple()