Usually, when you write a function, you define exactly how many arguments it takes. But what if you’re throwing a party and you don’t know how many people will show up?
*args: Like telling your friend, “Bring whoever you want.” They show up with a group (a Tuple).**kwargs: Like saying, “Bring whoever you want, but everyone needs to wear a name tag (Labels).” They show up with a group where everyone has a specific role (a Dictionary).
Packing Arguments with *args
When you use one asterisk (*), Python “packs” all the extra positional arguments into a single Tuple
def make_pizza(size, *toppings):
# 'toppings' is now a tuple: ("pepperoni", "cheese", "mushrooms")
print(f"Making a {size} inch pizza with:")
for topping in toppings:
print(f"- {topping}")
make_pizza(12, "pepperoni", "cheese", "mushrooms")
Packing Keyword Arguments with **kwargs
Two asterisks (**) handle “Labeled” inputs (Keyword Arguments). Python packs these into a Dictionary.
def build_profile(first, last, **user_info):
# 'user_info' is a dictionary: {'location': 'Poland', 'field': 'IT'}
print(f"User: {first} {last}")
for key, value in user_info.items():
print(f"{key.title()}: {value}")
build_profile("Daniel", "Adrian", location="Poland", field="IT")
Do the names args and kwargs matter? No. You could call them *people and **labels. The names are just a convention, the asterisks are what do the magic. However, always use args and kwargs, as this is common practice.
Unpacking into Functions
You can also use these tools in reverse. If you already have a list or dictionary, you can “explode” it into a function call. This is much cleaner than typing out every index or key manually.
def describe_car(brand, model, year):
print(f"This is a {year} {brand} {model}.")
# List Unpacking (*)
car_list = ["Tesla", "Model 3", 2024]
describe_car(*car_list)
# Dictionary Unpacking (**)
# Important: The keys MUST match the function's parameter names!
car_dict = {"brand": "Ford", "model": "Mustang", "year": 1969}
describe_car(**car_dict)
Parameter order
If you want to use everything in one function, you must follow this specific order. If you mix them up, Python will throw a SyntaxError.
- Standard arguments (e.g.,
name) *args(Positional packing)**kwargs(Keyword packing)
def master_function(name, *args, **kwargs):
print(f"Hello {name}")
print(f"Extra stuff: {args}")
print(f"Labeled stuff: {kwargs}")
master_function("Daniel", 1, 2, 3, status="Admin", active=True)