4.11 Arbitrary Argument Lists

Functions with arbitrary argument lists, such as built-in functions min and max, can receive any number of arguments. Consider the following min call:


min(88, 75, 96, 55, 83)

The function’s documentation states that min has two required parameters (named arg1 and arg2) and an optional third parameter of the form *args, indicating that the function can receive any number of additional arguments. The * before the parameter name tells Python to pack any remaining arguments into a tuple that’s passed to the args parameter. In the call above, parameter arg1 receives 88, parameter arg2 receives 75 and parameter args receives the tuple (96, 55, 83).

Defining a Function with an Arbitrary Argument List

Let’s define an average function that can receive any number of arguments:


In [1]: def average(*args):
   ...: return sum(args) / len(args)
   ...:

The parameter name args is used by convention, but you may use any identifier. If the function has multiple parameters, the *args parameter must be the rightmost parameter.

Now, let’s call average several times with arbitrary argument lists of different lengths:


In [2]: average(5, 10)
Out[2]: 7.5

In [3]: average(5, 10, 15)
Out[3]: 10.0

In [4]: average(5, 10, 15, 20)
Out[4]: 12.5

To calculate the average, divide the sum of the args tuple’s elements (returned by built-in function sum) by the tuple’s number of elements (returned by built-in function len). Note in our average definition that if the length of args is 0, a ZeroDivisionError occurs. In the next chapter, you’ll see how to access a tuple’s elements without unpacking them.

Passing an Iterable’s Individual Elements as Function Arguments

You can unpack a tuple’s, list’s or other iterable’s elements to pass them as individual function arguments. The * operator, when applied to an iterable argument in a function call, unpacks its elements. The following code creates a five-element grades list, then uses the expression *grades to unpack its elements as average’s arguments:


In [5]: grades = [88, 75, 96, 55, 83]

In [6]: average(*grades)
Out[6]: 79.4

The call shown above is equivalent to average(88, 75, 96, 55, 83).

Self Check

  1. (Fill-In) To define a function with an arbitrary argument list, specify a parameter of the form      .
    Answer: *args (again, the name args is used by convention, but is not required).

  2. (IPython Session) Create a function named calculate_product that receives an arbitrary argument list and returns the product of all the arguments. Call the function with the arguments 10, 20 and 30, then with the sequence of integers produced by range(1, 6, 2).
    Answer:

    
    In [1]: def calculate_product(*args):
       ...:     product = 1
       ...:     for value in args:
       ...:         product *= value
       ...:     return product
       ...:
    In [2]: calculate_product(10, 20, 30)
    Out[2]: 6000
    In [3]: calculate_product(*range(1, 6, 2))
    Out[3]: 15