PyComplete Python Course
Intermediate 35 min

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.

Syntax
def func(a, b, *args, **kwargs):
    print(a, b)
    print(args)      # tuple of extra positional args
    print(kwargs)     # dict of extra keyword args

Examples

*args basics Very Easy

*args basics
def total(*numbers):
    return sum(numbers)
 
print(total(1, 2))
print(total(1, 2, 3, 4, 5))
Output3 15

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

*args with normal parameters
def describe(name, *hobbies):
    print(f"{name} enjoys: {', '.join(hobbies)}")
 
describe("Ada", "chess", "coding", "reading")
OutputAda enjoys: chess, coding, reading

name grabs the first argument as usual; every remaining positional argument flows into the hobbies tuple.

**kwargs basics Intermediate

**kwargs basics
def build_profile(**details):
    for key, value in details.items():
        print(f"{key}: {value}")
 
build_profile(name="Ada", role="Engineer", city="London")
Outputname: 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

Using both together
def order(item, *extras, **notes):
    print("Item:", item)
    print("Extras:", extras)
    print("Notes:", notes)
 
order("Burger", "cheese", "bacon", spicy=True, delivery="ASAP")
OutputItem: Burger Extras: ('cheese', 'bacon') Notes: {'spicy': True, 'delivery': 'ASAP'}

Parameter order matters: regular parameters first, then *args, then **kwargs β€” Python enforces this order in the function signature.

Visual Explanation

Call: order("Burger", "cheese", "bacon", spicy=True)item = "Burger"extras = ("cheese", "bacon") ← packed by *argsnotes = {"spicy": True} ← packed by **kwargs
Extra positional arguments flow into *args as a tuple; extra keyword arguments flow into **kwargs as a dictionary.
πŸ’‘ 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

βœ— Common mistake 1

*args must come before **kwargs in a function definition, and neither can come before a required positional parameter.

βœ— Avoid this
This raises SyntaxError: invalid syntax
def func(**kwargs, *args):
    pass
βœ“ Better approach
Fixed
def func(*args, **kwargs):
    pass
βœ“ Best practices
  • 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

Given this code
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
Python
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?

A list
A tuple
A dictionary
A set
*args collects extra positional arguments into a tuple.

2. What data type does **kwargs collect its values into?

A list
A tuple
A dictionary
A set
**kwargs collects extra keyword arguments into a dictionary.

3. In a function signature, what order must these appear in?

**kwargs, *args, regular params
regular params, *args, **kwargs
*args, regular params, **kwargs
Order never matters
Regular parameters come first, then *args, then **kwargs.

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.

Related lessons

Saved privately in your browser β€” no account needed.