DSC 20 Reader · Args and Kwargs
Starting Python…

Course weeks 6–7

Args and Kwargs

A function normally accepts exactly the parameters you list. Sometimes you do not know in advance how many inputs a caller will send. The stars * and ** let one function accept any number of arguments, and they let you pass a whole list or dictionary in as separate arguments.

By the end of this chapter you can

  • Write a function that accepts any number of positional arguments with *args.
  • Write a function that accepts any number of named arguments with **kwargs.
  • Say what type args and kwargs have inside the function.
  • Use * and ** in a call to unpack a list or a dictionary into separate arguments.
  • Put the parameters in a legal order.

1The problem with fixed parameters

A function with three named parameters accepts exactly three arguments. Run the cell below. The first call works. The second call sends four arguments, so Python stops with an error.

Read the message: it says the function takes 3 positional arguments but 4 were given. You could write a second function for four scores and a third for five, but there is no end to that. Variable arguments solve this with one function.

2*args: any number of positional arguments

Put a single star in front of a parameter name, and Python gathers all the extra positional arguments into one tuple under that name. A positional argument is one passed by its position, like best_of_three(70, 88, 92), with no name attached.

Because args is an ordinary tuple, everything you know about tuples applies: you can loop over it, index it, and take its length. Here is a version of the best-score function that works for any number of scores. With no scores at all, it returns None.

Regular parameters can come before the starred one. They take the first arguments, and *args collects whatever is left.

3Unpacking with * in a call

The star also works in calls. In this section the function has ordinary, regular parameters, and the star appears only where the function is called. A star in front of a list or tuple spreads its items out as separate arguments, one item for each parameter.

Both calls do the same thing, and the star saves you from writing each index. Without the star, the whole list is passed as a single argument, so the function receives one value and is missing the other two. Run the cell and read the message.

The list went to the first parameter, month, and nothing was left for day and year. The number of items you unpack has to match the number of parameters the function expects.

Mixing unpacked and regular arguments

You can combine a starred list with ordinary arguments in the same call. Python matches everything to the parameters from left to right.

Predict the output of this cell before you run it.

Show the answer

It prints 5.0. The star unpacks the tuple (3, 4), so x is 3 and y is 4. The call is the same as distance(3, 4).

Predict the two numbers before you run the cell.

Show the answer

It prints 1, then 3. In the first call the list letters is one argument, so args is a tuple holding one item, the list. In the second call the star unpacks the list, so args holds the three letters.

Quick check
Inside def f(*args), what type is args?

4**kwargs: any number of named arguments

A keyword argument is one passed with a name, like f(x=10). Put two stars in front of a parameter name, and Python gathers all the extra keyword arguments into a dictionary. The names become the keys and the values become the values.

Since kwargs is a dictionary, you loop over it with .items(), exactly as in the dictionary section of the course.

Unpacking a dictionary with **

In a call, two stars in front of a dictionary turn each key and value into a named argument. The keys must match the parameter names of the function.

Show the fix

The message says format_name() got an unexpected keyword argument 'surname'. The function has a parameter called last, not surname. Rename the key to "last" and it works.

5Using both

A function can take regular parameters, *args, and **kwargs together. Positional arguments fill the regular parameters first, extra positional ones go to args, and named ones go to kwargs.

Quick check
Which definition has a legal parameter order?

6The names are a convention

Python only looks at the stars. The words args and kwargs are what most programmers write, so other people will recognize them, but any valid name works. A descriptive name is often clearer.

7Practice

Exercise 1: any number of inputs

Write average(*numbers). It returns the average of all the numbers it receives. If it receives none, it returns 0.

Hint

Inside the function, numbers is a tuple. You can take its length with len and add its items with sum. An empty tuple is falsy, so if not numbers: catches the case with no arguments before you divide by zero.

Exercise 2: any number of named inputs

Write describe_options(**options). It returns the options as text in the form key=value, separated by a comma and a space, in the order they were given. If there are no options, it returns "none".

Hint

Inside the function, options is a dictionary. Build a list of "key=value" strings with a loop over options.items(), then join the list with ", ".join(...).