*args and **kwargs
Write functions that accept any number of arguments — the *args and **kwargs pattern used throughout real Python code.
"*args collects any number of positional arguments into a tuple. **kwargs collects any number of keyword arguments into a dictionary. Together they make your functions completely flexible."
— ShurAIThe Problem: Fixed Number of Parameters
Normal functions require exactly the number of arguments you declared. What if you don't know in advance how many there will be?
def add(a, b):
return a + b
add(1, 2) # works
add(1, 2, 3) # TypeError: add() takes 2 positional arguments but 3 were given
*args — Any Number of Positional Arguments
The * before a parameter name collects all extra positional arguments into a tuple. The name args is convention — the star is what matters:
def add(*args):
print(type(args)) # <class 'tuple'>
return sum(args)
print(add(1, 2)) # 3
print(add(1, 2, 3)) # 6
print(add(10, 20, 30, 40)) # 100
print(add()) # 0 — empty tuple is fine
Mixing Regular + *args
def greet(greeting, *names):
"""Say greeting to every name provided."""
for name in names:
print(f"{greeting}, {name}!")
greet("Hello", "Riya")
greet("Good morning", "Arjun", "Sneha", "Vikram")
Hello, Riya!
Good morning, Arjun!
Good morning, Sneha!
Good morning, Vikram!
**kwargs — Any Number of Keyword Arguments
The ** prefix collects all extra keyword arguments into a dictionary. Perfect when you want named, optional settings:
def show_profile(**kwargs):
print(type(kwargs)) # <class 'dict'>
for key, val in kwargs.items():
print(f" {key}: {val}")
show_profile(name="Riya", age=22, city="Mumbai")
print()
show_profile(product="Rice", price=280)
name: Riya
age: 22
city: Mumbai
product: Rice
price: 280
Using Both Together
Order rule: regular first, then *args, then **kwargs:
def order_food(table, *dishes, **options):
print(f"Table {table}:")
print(f" Dishes : {list(dishes)}")
print(f" Options: {options}")
order_food(
5,
"Biryani", "Naan", "Raita",
spice="medium", takeaway=False
)
Table 5:
Dishes : ['Biryani', 'Naan', 'Raita']
Options: {'spice': 'medium', 'takeaway': False}
Quick Summary
*Collects positional args
Inside function: a tuple
Loop with:
for x in args
**Collects keyword args
Inside function: a dict
Loop with:
for k,v in kwargs.items()
"*args and **kwargs are the secret behind Python's most flexible functions. Once you understand them, you'll see them used all the time in libraries."
— ShurAI🧠 Quiz — Q1
Inside a function, what data type does *args give you?
🧠 Quiz — Q2
Inside a function, what data type does **kwargs give you?
🧠 Quiz — Q3
What is the correct order of parameters in a function definition?
🧠 Quiz — Q4
Given def f(**opts): print(opts), what does f(color="red", size=10) print?