Module 10 β *args and **kwargs
Writing functions that accept any number of arguments.
Prerequisite: Module 05 β Functions
After this lesson, you will be able to
- Accept any number of positional arguments with *args
- Accept any number of named arguments with **kwargs
- Order regular, *args, and **kwargs parameters correctly
Concept & Syntax
Sometimes you don't know in advance how many arguments a function will need β think of a sum_all()
function that should work whether you pass it 2 numbers or 20. *args collects any number of extra
positional arguments into a tuple; **kwargs collects any number of extra named arguments into a
dictionary. The names args and kwargs are just convention β the asterisks are what
actually matter.
def func(a, b, *args, **kwargs):
print(a, b)
print(args) # tuple of extra positional args
print(kwargs) # dict of extra keyword argsExamples
*args basics Very Easy
def total(*numbers):
return sum(numbers)
print(total(1, 2))
print(total(1, 2, 3, 4, 5))numbers becomes a tuple containing whatever positional arguments were passed β sum() adds them all up regardless of how many there are.
*args with normal parameters Easy
def describe(name, *hobbies):
print(f"{name} enjoys: {', '.join(hobbies)}")
describe("Ada", "chess", "coding", "reading")name grabs the first argument as usual; every remaining positional argument flows into the hobbies tuple.
**kwargs basics Intermediate
def build_profile(**details):
for key, value in details.items():
print(f"{key}: {value}")
build_profile(name="Ada", role="Engineer", city="London")details becomes a dictionary of every keyword argument passed in, letting the caller supply any named fields they like.
Using both together Real World
def order(item, *extras, **notes):
print("Item:", item)
print("Extras:", extras)
print("Notes:", notes)
order("Burger", "cheese", "bacon", spicy=True, delivery="ASAP")Parameter order matters: regular parameters first, then *args, then **kwargs β Python enforces this order in the function signature.
Visual Explanation
π‘ Why does this work?
Read the concept explanation above again slowly, line by line β every keyword there maps directly onto a line of code in the examples. If it still doesn't click, re-run the traced example (if this lesson has one) one step at a time.
π What happens internally? (advanced)
Under the hood, Python compiles your source into bytecode and runs it on a virtual machine (the CPython interpreter). Variables are names in a namespace dictionary pointing at objects in memory β which is exactly what the memory panel in the tracer above is showing you.
Common Mistakes
*args must come before **kwargs in a function definition, and neither can come before a required positional parameter.
def func(**kwargs, *args):
passdef func(*args, **kwargs):
pass- Only use *args/**kwargs when the number of arguments genuinely varies β don't overuse them where named parameters would be clearer.
- Document what kinds of extra arguments a function expects, even though Python won't enforce it.
- Unpack an existing list/dict into a call with my_func(*my_list, **my_dict) when useful.
Exercise & Challenge
Exercise 1 β Predict the output
def show(*args):
print(len(args))
show(1, 2, 3, 4)What does this print?
π Challenge
Write a function make_pizza(size, *toppings) that prints the pizza size and a comma-separated list of toppings, then call it with a size and at least 3 toppings.
- size should be a required, named parameter
- toppings should collect any number of extra arguments
- Print a friendly summary sentence
π‘ Need a hint?
', '.join(toppings) turns the tuple into a readable string.
π Show a sample solution
def make_pizza(size, *toppings):
print(f"Making a {size}-inch pizza with: {', '.join(toppings)}")
make_pizza(12, "cheese", "mushroom", "olives")Quiz
Answer every question, then submit to see your score and explanations.
1. What data type does *args collect its values into?
2. What data type does **kwargs collect its values into?
3. In a function signature, what order must these appear in?
Summary
- *args lets a function accept any number of extra positional arguments, as a tuple.
- **kwargs lets a function accept any number of extra named arguments, as a dictionary.
- Parameter order is always: regular parameters, then *args, then **kwargs.