Python for Programmers: Variadic Functions
Welcome to the Variadic Functions lesson!
This lesson is shown as static text below. However, it's designed to be used interactively. Click the button below to start!
Most functions take a fixed number of arguments, like
def add(x, y). We can also define functions that take a variable number of arguments, called "variadic functions."In a variadic function, extra arguments are collected in a tuple that we write as
*argsin the argument list.>
def my_sum(*args):total = 0for arg in args:total += argreturn total- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
my_sum(1, 2, 3)Result:
6
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
my_sum(1, 10, 100, 1000, 10000)Result:
11111
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
my_sum()Result:
0
A function can take normal positional arguments along with variadic arguments. In the next example, the function appends a value to many lists at once. To do this, we pass in a value to append, followed by an arbitrary number of lists. (Remember, appending mutates lists.)
>
def append_many(value, *lists):for l in lists:l.append(value)list_1 = [1, 2]list_2 = [3, 4]append_many(5, list_1, list_2)- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
list_1Result:
[1, 2, 5]
- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
list_2Result:
[3, 4, 5]
Functions can also accept an arbitrary number of keyword arguments ("variadic kwargs") using a
**instead of a single*.The next function calculates the lengths of many lists. We pass the lists in as kwargs, then get a dictionary back that maps the kwargs' names to the lists' lengths.
Note that
kwargs.items()gives us an iterable of tuples, one per keyword argument, like(key, value).>
def list_lengths(**kwargs):return {key: len(values)for (key, values) in kwargs.items()}list_lengths(a=[1, 2, 3], b=[4, 5])Result:
We can combine
*argsand**kwargsin one function. This gives us a function that can accept any set of arguments: positional, keyword, a mixture of both, or no arguments at all.The
count_argsfunction below returns a tuple with counts of how many*argsand**kwargswe passed. It can be called with any set of arguments.>
def count_args(*args, **kwargs):return (len(args), len(kwargs))count_args(1, 2, 3, name="Amir")Result:
(3, 1)
As before, kwargs must still come after positional arguments. Otherwise, it's a
SyntaxError.- Note: this code example reuses elements (variables, etc.) defined in earlier examples.
>
count_args(age=36, 1, 2, 3, name="Amir")Result:
SyntaxError: positional argument follows keyword argument (<string>, line 6)
What if a function takes
*argsbut we pass no arguments? Theargsvariable still exists inside the function body, but it's the empty tuple,().>
def return_args(*args):return argsreturn_args()Result:
()
We get a similar result when a function takes
**kwargsbut we don't pass any: we get an empty dictionary,{}.>
def return_kwargs(**kwargs):return kwargsreturn_kwargs()Result:
{}Lambdas can also take
*args,**kwargs, neither, or both.>
count_args = lambda *args, **kwargs: (len(args), len(kwargs))count_args(1, name="Amir", age=36)Result:
(1, 2)
Finally, a note on terminology. There are a few different terms for variadic functions, all of which are in common use.
"Variadic function" is the standard technical term, both in computer science and mathematics. Python documentation refers to this language feature as "argument packing". In casual conversations about Python,
*argsand**kwargsare also called "splat args". ("Splat" is a slang term for the*character, since it looks like a splat of paint or a splattered bug.)