How To Use *args and **kwargs in Python 3
Practical guide to python *args and **kwargs: how to use, pack/unpack, argument order, examples, and common mistakes.
Drake Nguyen
Founder · System Architect
Introduction
This guide explains python *args and **kwargs: how they let functions accept a variable number of arguments, when to use them, and common pitfalls. You’ll learn both *args in python (for positional values) and **kwargs in python (for keyworded values), plus examples of packing and unpacking arguments in Python 3.
Prerequisites
Have Python 3 available and a text editor or REPL. Basic familiarity with function definitions, tuples, lists, and dictionaries will make the examples easier to follow.
Understanding *args
The single-asterisk form packs additional positional parameters into a tuple. The identifier args is a convention; the important part is the asterisk (*). Use *args when you want a function to accept a variable number of positional arguments.
def multiply(*args):
result = 1
for n in args:
result *= n
print(result)
multiply(5, 4) # 20
multiply(2, 3, 4) # 24
Inside multiply, args is a tuple of the passed values. This pattern is useful for variadic functions and when you don’t know how many positional arguments callers will supply.
Understanding **kwargs
The double-asterisk form collects extra keyword (named) arguments into a dictionary. The common name is kwargs, but any valid identifier works; the key is the ** operator. Use **kwargs in python when callers should supply named values that you want to access by key.
def print_kwargs(**kwargs):
print(kwargs)
print_kwargs(a=1, name='Sammy', active=True)
# {'a': 1, 'name': 'Sammy', 'active': True}
You can iterate over kwargs just like any dictionary:
def greet_all(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
greet_all(first='Alex', second='Casey')
Argument order and keyword-only parameters
Python requires a specific order in function signatures. Stick to this sequence to avoid syntax errors and unexpected behavior:
- Formal positional parameters
- *args (variadic positional)
- Named keyword parameters (with or without defaults)
- **kwargs (variadic keyword)
def example(a, b, *args, kw1='x', kw2='y', **kwargs):
pass
Placing *args before keyword-only parameters allows you to create keyword-only arguments (parameters that must be specified by name). For example:
def func(a, *args, only_kw):
# only_kw is keyword-only and required
print(a, args, only_kw)
# func(1, 2, 3, 4) # TypeError: missing required keyword-only argument 'only_kw'
func(1, 2, only_kw='value') # valid
Common mistakes
- Forgetting the asterisk when unpacking: f(*my_list) vs f(my_list).
- Expecting **kwargs to preserve insertion order on older Python versions (prior to 3.6 dictionaries were unordered).
- Naming the parameter something misleading — use conventional names like *args and **kwargs for clarity.
- Mixing positional-only expectations with **kwargs without handling unexpected keys.
Packing and unpacking in calls
You can pack arguments inside functions and unpack iterables or mappings when calling functions.
# Unpack a list/tuple into positional arguments
def show(a, b, c):
print(a, b, c)
values = [1, 2, 3]
show(*values) # same as show(1, 2, 3)
# Unpack a dict into keyword arguments
def describe(name, age):
print(name, age)
info = {'name': 'Alex', 'age': 30}
describe(**info) # same as describe(name='Alex', age=30)
Combining explicit parameters with *args and **kwargs in calls:
def summary(a, b, *args, **kwargs):
print(a, b, args, kwargs)
lst = [3, 4]
dct = {'x': 10, 'y': 20}
summary(1, 2, *lst, **dct)
# prints: 1 2 (3, 4) {'x': 10, 'y': 20}
When to use and when to avoid
- Use python variable arguments for wrapper functions, simple aggregators, or APIs where flexibility is needed.
- Avoid overusing them in public APIs where explicit parameters improve readability and maintainability.
- Prefer explicit parameters when the argument list is well defined; use *args/**kwargs to add optional extensibility.
Tips
- Document what additional positional or keyword arguments are accepted.
- Validate keys in **kwargs if your function expects only certain names.
- Use keyword-only parameters to make callers’ intent explicit.
Conclusion
Mastering python *args and **kwargs lets you write flexible functions that accept variable positional and keyword arguments. Remember the correct parameter order, prefer clear names, and use packing/unpacking (* and **) when calling functions. The techniques shown here include examples of how to use *args and **kwargs in python 3, how to unpack lists with * and dictionaries with **, and common mistakes to avoid.