*args and **kwargs
Functions that take any number of arguments.
4 minute read
Big idea
*args lets a function take any number of positional arguments, collected into a tuple. **kwargs collects any number of keyword arguments into a dict.
*args
You've already used a function like this — print takes as many values as you give it. Write your own with a * before a parameter name:
def total(*numbers):
print(numbers)
return sum(numbers)
print(total(1, 2))
print(total(5, 10, 15, 20))
print(total())output
(1, 2)
3
(5, 10, 15, 20)
50
()
0Run and edit it in the app.
Inside the function, numbers is a tuple of everything passed. The name args is just a convention; the * is what matters.
Mixing with normal parameters
Normal parameters come first and take the first arguments; *args mops up the rest:
def announce(title, *names):
print(title + ":", ", ".join(names))
announce("Winners", "Ada", "Grace", "Linus")
announce("Nobody")What does it print? Show the answer
Winners: Ada, Grace, Linus
Nobody:Run and edit it in the app.
**kwargs
Two stars collect keyword arguments into a dict:
def profile(name, **details):
print(name)
for key, value in details.items():
print(f" {key}: {value}")
profile("Ada", born=1815, field="mathematics")output
Ada
born: 1815
field: mathematicsRun and edit it in the app.
Unpacking into a call
The stars also work the other way: * spreads a list into separate arguments, ** spreads a dict into keyword arguments.
def area(width, height):
return width * height
size = [3, 7]
print(area(*size))
options = {"width": 2, "height": 5}
print(area(**options))output
21
10Run and edit it in the app.
def largest(*nums):
best = nums[0]
for n in nums:
if n > best:
best = n
return best
values = [4, 19, 7]
print(largest(values))output
19Run and edit it in the app.
Without a star, largest(values) passes one argument — the whole list — so nums is ([4, 19, 7],). Call largest(*values) to spread it out.
The full order
When you combine them all, the order is fixed: normal parameters, *args, keyword-only parameters, then **kwargs. Most functions need only one or two of these.
def f(*args): return args — what does f(1, 2, 3) return?
Watch it
Think of it like
A bag at the door of a party: everyone who turns up without a reserved seat (a named parameter) drops their coat in it. *args is the bag for unnamed guests; **kwargs is the bag where every coat has a name tag.
Key terms
- *args — Collects extra positional arguments into a tuple.
- **kwargs — Collects extra keyword arguments into a dict.
- Unpacking in a call —
f(*list)orf(**dict)spreads values into arguments.
Check yourself
Inside def f(*args), what type is args?
What does **kwargs collect?
nums = [1, 2]. How do you pass them as two separate arguments to f?