Functions and Objects · Functions · lesson 3 of 10
*args and **kwargs
about 14 minutes · free · runs in your browser
Step 1 of 2
Any number of arguments
*args collects every extra positional argument into a tuple:
def total(*numbers):
return sum(numbers)
total(1, 2, 3) # 6
total() # 0
**kwargs collects every extra keyword argument into a dictionary:
def describe(**details):
return details
describe(name="Ada", age=36) # {"name": "Ada", "age": 36}
The names args and kwargs are only convention — the * and ** do the work.
The same symbols work in reverse at the call site, spreading a list or dictionary out into arguments:
numbers = [1, 2, 3]
total(*numbers) # same as total(1, 2, 3)
Your turn: write summarise(*values, **options) returning a dictionary with the
count of values, their total, and a label taken from the options (defaulting to
"summary").
You start from this, and edit it in the browser:
def summarise(*values, **options):
# Return {"count": ..., "total": ..., "label": ...}
pass
Step 2 of 2
Spreading arguments
* and ** at a call site do the opposite of what they do in a definition: they
unpack a collection into separate arguments.
def make(name, colour):
return f"{colour} {name}"
parts = {"name": "car", "colour": "red"}
make(**parts) # "red car"
This is how wrapper functions pass whatever they were given straight through.
Your turn: write apply_all(fn, arg_lists) where arg_lists is a list of argument
lists. Call fn once per entry, spreading each list, and return the results.
You start from this, and edit it in the browser:
def apply_all(fn, arg_lists):
# Call fn(*args) for each entry and collect the results.
pass