简体   繁体   中英

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

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. 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. Did it unpack list z just to extract the 1st element from z then keeping rest of z as it is? If that can be done with a list then how?

Also, If I call the function with z alone as argument, it throws error

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'

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)

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?

Not really. First, z was unpacked and each argument passed in separately (as mentioned above). So now you have we look at the definition of mean: def mean(x, *l): . This definition is expecting at least one positional argument ( x ), and than any number of extra arguments . 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) .

Also, If I call the function with z alone as argument, it throws error

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. 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)) . Now, because x is a list, Python raises an exception because it does not know how to compute [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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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