简体   繁体   English

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

[英]How list unpacking works when passed as argument to function with variable parameters?

I have a function which calculates arithmetic mean of variable parameter list.我有一个计算可变参数列表的算术平均值的函数。 It has one positional parameter and rest variable parameter.它有一个位置参数和剩余变量参数。 So the code is shown below.所以代码如下所示。

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

Now I define a list containing var arguments现在我定义了一个包含 var 参数的列表

z = [1,2,3,4]

Now I call my function现在我调用我的函数

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

So what happened here?那么这里发生了什么? My understanding is when I did *z it unpacked the list z.我的理解是,当我执行 *z 时,它会解压列表 z。 But then how it picked the 1st positional parameter from the list and kept the rest of the list intact to get the length of 'l' as defined in the function mean.但是然后它如何从列表中选择第一个位置参数并保持列表的其余部分完好无损以获得函数 mean 中定义的“l”的长度。 Did it unpack list z just to extract the 1st element from z then keeping rest of z as it is?是否解压列表 z 只是为了从 z 中提取第一个元素然后保持 z 的其余部分原样? If that can be done with a list then how?如果可以用列表来完成,那么如何?

Also, If I call the function with z alone as argument, it throws error另外,如果我单独使用 z 作为参数调用该函数,则会引发错误

ari_mean(z) Traceback (most recent call last): File "", line 1, in File "", line 5, in ari_mean TypeError: unsupported operand type(s) for /: 'list' and 'float' ari_mean(z) 回溯(最近一次调用最后一次):文件“”,第 1 行,在文件“”,第 5 行,在 ari_mean 中 TypeError:不支持的操作数类型 /:'list' 和 'float'

Thanks.谢谢。

When you call mean(*z) , you are correct in that Python unpacks z , which means that your function call is equivalent (in this case), to calling mean(1, 2, 3, 4)当你调用mean(*z) ,你是正确的,Python 解包z ,这意味着你的函数调用等效(在这种情况下),调用mean(1, 2, 3, 4)

Now, on to the second part of your question:现在,进入问题的第二部分:

Did it unpack list z just to extract the 1st element from z then keeping rest of z as it is?是否解压列表 z 只是为了从 z 中提取第一个元素然后保持 z 的其余部分原样?

Not really.并不真地。 First, z was unpacked and each argument passed in separately (as mentioned above).首先, z被解包,每个参数分别传入(如上所述)。 So now you have we look at the definition of mean: def mean(x, *l): .所以现在你让我们看看 mean 的定义: def mean(x, *l): This definition is expecting at least one positional argument ( x ), and than any number of extra arguments .这个定义需要至少一个位置参数 ( x ),而不是任意数量的额外参数 So, because your initial call of mean(*z) got turned into mean(1, 2, 3, 4) , then inside your mean , x is equal to 1 and *l becomes the tuple (2, 3, 4) .因此,因为您对mean(*z)初始调用变成了mean(1, 2, 3, 4) ,然后在您的mean内部, x等于1并且*l成为元组(2, 3, 4)

Also, If I call the function with z alone as argument, it throws error另外,如果我单独使用 z 作为参数调用该函数,则会引发错误

If you just call the function with z alone ( mean(z) ), then, going back to your function definition, x will be the list [1,2,3,4] and l will be an empty tuple.如果你只是用 z 单独调用函数( mean(z) ),那么,回到你的函数定义, x将是列表[1,2,3,4]l将是一个空元组。 Because l is an empty tuple, nothing happens in the for-loop, and you get to the last line, return sum / (1.0 + len(l)) .因为l是一个空元组,所以 for 循环中什么也没有发生,你到了最后一行, return sum / (1.0 + len(l)) Now, because x is a list, Python raises an exception because it does not know how to compute [1,2,3,4] / 1.0现在,因为x是一个列表,Python 会引发异常,因为它不知道如何计算[1,2,3,4] / 1.0

Running the code below can show you how it works, the comments present the way the arguments are passed in the function.运行下面的代码可以向您展示它是如何工作的,注释显示了在函数中传递参数的方式。

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM