How can you make a Python function that accepts any number of positional arguments?
Passing Arguments to a Function
Here's a function (called
greet) that accepts a single argument (
>>> def greet(name):... print("Hello", name)...
We can pass that argument in positionally:
>>> greet("Trey")Hello Trey
Or as a keyword argument:
>>> greet(name="Trey")Hello Trey
If we pass in 2 names or 3 names to this function, we'll get an error:
>>> greet("Trey", "Jo")Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: greet() takes 1 positional argument but 2 were given>>> greet("Trey", "Jo", "Ian")Traceback (most recent call last): File "<stdin>", line 1, in <module>TypeError: greet() takes 1 positional argument but 3 were given
We'd like to modify this function to accept any number of names (and to greet each name given).
Asterisks can pack multiple arguments
To accept any number of positional arguments we're going to need to use the
* operator when defining this function.We'll replace
>>> def greet(*names):... for name in names:... print("Hello", name)...
*names in our arguments tells Python that we want to capture all positional arguments given to this function, into a tuple, point the
names variable to that tuple.
Now when we call
greet with just one name, it works the same as before:
>>> greet("Trey")Hello Trey
But we can also call it with multiple names to greet multiple people:
>>> greet("Trey", "Jo")Hello TreyHello Jo>>> greet("Trey", "Jo", "Ian")Hello TreyHello JoHello Ian
In fact, we can even call it with no names:
names tuple in the
greet function is empty in this case so the loop does nothing.It's not an error to give zero arguments when you're using
Built-In function use argument packing
What are examples of functions that accept any number of positional arguments?
A number of Python's built-in functions actually work this way. For example, the
zip function accepts any number of iterables to loop over at the same time:
>>> help(zip)class zip(object) | zip(*iterables) --> zip object
*iterables in the definition of the
zip function (
zip class technically) means it accepts any number of iterables.When you give
zip loop over all of those iterables at the same time.
min(arg1, arg2, *args, *[, key=func]) -> value
Note in that in the
min documentation that
arg2 are before
*args.It's possible to define your own functions like this.We can put other (required) positional arguments before all the remaining (optional) positional arguments that we're capturing.
You can also pass any number of arguments to the
>>> help(print)print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
The documentation is a little bit different with
* operator (instead it shows
... to indicate that any number of values are accepted).
You can give any number of arguments to
>>> print(1, 2, 3, 4)1 2 3 4
To make a function that accepts any number of arguments, you can use the
* operator and then some variable name when defining your function's arguments.This lets Python know that when that function is called with any position arguments, they should all be captured into a tuple (which that variable will point to).
So if you'd like to make a function that accepts any number of positional arguments, use the