Skip to content

Intermediate · Functions · topic 20 of 50 · 20 min

*args and **kwargs

Explanation

*args lets a function accept any number of positional arguments, which arrive as a tuple. **kwargs collects any number of keyword arguments into a dict. When calling, * and ** do the opposite and spread a list or dict into separate arguments. Parameters after * can only be passed by name.

Any number of arguments: *args

Sometimes you do not know how many values someone will pass. Put a star before a parameter name, like *prices, and Python collects all the extra positional arguments into one tuple with that name. The usual name is *args, short for arguments, but any name works; the star is what matters.

python
def total(*prices):
    print(prices)
    return sum(prices)

print(total(40, 25, 60))
print(total())
prices is a tuple: (40, 25, 60), so the total is 125. With no arguments it is an empty tuple, and the total is 0.
Think of it like this: A *args parameter is like a shopping bag at the sabzi market. You do not tell the bag in advance how many vegetables you will buy. You keep putting things in, and at home you take them all out together. **kwargs is like a bag of labelled packets: each thing comes with its name written on it.

Any number of keyword arguments: **kwargs

python
def profile(name, **details):
    print(name)
    for key, value in details.items():
        print(" ", key, "=", value)

profile("Asha", city="Pune", age=21)
Two stars collect the extra keyword arguments into a dict, here with the keys city and age. The usual name is **kwargs, short for keyword arguments.

Unpacking when you call: * and **

The stars also work the other way round. When you call a function, *my_list spreads the items of a list into separate positional arguments, and **my_dict spreads a dict into keyword arguments.

python
def describe(name, city):
    return name + " from " + city

pair = ["Ravi", "Chennai"]
info = {"name": "Meena", "city": "Kochi"}
print(describe(*pair))
print(describe(**info))
describe(*pair) is the same as describe("Ravi", "Chennai"). describe(**info) is the same as describe(name="Meena", city="Kochi").

Keyword-only arguments

A parameter that comes after *args, or after a lone *, can only be passed by name. These are called keyword-only arguments. They are useful for options, so that nobody passes True or False in the wrong position by mistake.

python
def book_ticket(name, *, seat="any", meal=False):
    return name + ": seat " + seat + ", meal " + str(meal)

print(book_ticket("Asha", seat="window", meal=True))
print(book_ticket("Ravi"))
seat and meal come after the lone *, so they must be named when you pass them.
output
def book_ticket(name, *, seat="any"):
    return name + " " + seat

book_ticket("Asha", "window")
TypeError: book_ticket() takes 1 positional argument but 2 were given. seat must be passed as seat="window".

The order of parameters

OrderKindExample
1normal positionalname
2with a defaultcity="Pune"
3any number of positional*marks
4keyword-onlyurgent=False
5any number of keyword**extra
python
def report(name, city="Pune", *marks, urgent=False, **extra):
    print(name, city, marks, urgent, extra)

report("Asha", "Delhi", 80, 90, urgent=True, section="B")
Each argument lands in its place. Shows Asha Delhi (80, 90) True {'section': 'B'}.
Careful: Putting parameters in the wrong order, like def f(**kwargs, *args) or def f(a=1, b), is a SyntaxError. Also remember: inside the function, args is a tuple and kwargs is a dict, so use tuple and dict tools on them.
Tip: Do not use *args and **kwargs everywhere. Normal named parameters are clearer. Use the stars when the number of values really changes, like adding up any number of prices.

Watch the lesson

*args and **kwargs · 1/6

*args and **kwargs

In this lesson you will learn how a function can accept any number of arguments.

Prefer a video by a teacher? Find free videos on “python args kwargs explained for beginners” on YouTube ↗

In real life: A UPI payment summary

A small shop gets many UPI payments in a day, and the number changes every day. A function with *amounts can add up any number of payments. Extra details like the shop name and the date are optional, so they come in through **info and are printed only when given.

python
def day_summary(*amounts, **info):
    for key, value in info.items():
        print(key, ":", value)
    print("Payments:", len(amounts))
    print("Total: Rs", sum(amounts))

day_summary(120, 45, 300, 80, shop="Gupta Stores", day="Monday")
Prints the shop and day, then Payments: 4 and Total: Rs 545.

Practice (0/3 done)

Task 1 · Code · Python

Write a function total(*prices) that returns the sum of any number of prices. Example: total(10, 20, 30) returns 60 and total() returns 0.

Task 2 · Code · Python

Write a function make_profile(name, **details) that returns a dict with the key "name" set to name, plus every keyword argument that was passed. Example: make_profile("Asha", city="Pune") returns {"name": "Asha", "city": "Pune"}.

Task 3 · Code · Python

Write a function ticket_price(base, *, senior=False, tatkal=False). A senior citizen pays 60% of the base fare. Tatkal adds 200 rupees (after any senior discount). senior and tatkal are keyword-only. Example: ticket_price(1000, senior=True, tatkal=True) returns 800.

Quick quiz

Question 1

1.In def f(*args), what type is args?

Question 2

2.In def f(**kwargs), what does f(a=1, b=2) put in kwargs?

Question 3

3.def add(a, b, c): return a + b + c. nums = [1, 2, 3]. Which call returns 6?

Question 4

4.def f(a, *, b): ... Which call works?

Question 5

5.Which def line has the parameters in a valid order?

Read more (free)

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

← Previous: Parameters, arguments and defaults