Home Course Roadmap
Home Functions Lesson 32
Lesson 32 · Functions 45–55 minutes Beginner

*args & **kwargs

Learn how to create flexible Python functions that can accept a variable number of positional and keyword arguments using *args and **kwargs.

Functions Flexible Arguments Core Python
0%
01

What You Will Learn

By the end of this lesson, you will understand how Python functions can accept a flexible number of arguments.

  • Understand positional and keyword arguments.
  • Understand the purpose of *args.
  • Understand the purpose of **kwargs.
  • Understand why *args becomes a tuple.
  • Understand why **kwargs becomes a dictionary.
  • Use both techniques together.
  • Understand argument unpacking with * and **.
01

What Is *args?

Normally, a function is defined with a fixed number of parameters.

Fixed Parameters
def add(a, b):
    return a + b

print(add(10, 20))

What if you want the function to accept 2, 3, 5, or even 100 values?

This is where *args becomes useful.

Simple definition

*args allows a function to accept a variable number of positional arguments.

02

Why Use *args?

Consider a function that calculates a total. You may want to pass any number of prices.

Without *args
def add_three(a, b, c):
    return a + b + c

print(add_three(10, 20, 30))

This function only accepts exactly three values.

With *args, we can make the function much more flexible.

With *args
def add_numbers(*args):
    return sum(args)

print(add_numbers(10, 20))
print(add_numbers(10, 20, 30))
print(add_numbers(10, 20, 30, 40, 50))
Output
30
60
150
03

*args Syntax

The basic syntax is:

Syntax
def function_name(*args):
    # use args here
    pass

The name args is only a convention. Python cares about the *, not the word args.

Valid Alternative
def show_values(*values):
    print(values)

show_values(10, 20, 30)
Output
(10, 20, 30)

Still, *args is the widely recognized naming convention and should normally be preferred.

04

*args Is a Tuple

Inside the function, all extra positional arguments are collected into a tuple.

Tuple Behavior
def show_args(*args):
    print(args)
    print(type(args))

show_args("Python", "Java", "C++")
Output
('Python', 'Java', 'C++')
<class 'tuple'>
Remember

*args collects extra positional arguments into a tuple.

05

Looping Through *args

Because args is a tuple, you can loop through it just like any other tuple.

Loop Example
def print_names(*args):

    for name in args:
        print(name)

print_names("Ali", "Sara", "Ahmed")
Output
Ali
Sara
Ahmed
06

Indexing *args

Since args is a tuple, you can use indexing and slicing.

Indexing Example
def show_first(*args):

    print("First:", args[0])
    print("Last:", args[-1])

show_first("Python", "Java", "C++", "JavaScript")
Output
First: Python
Last: JavaScript
Be careful with empty args

If the function is called without arguments, args[0] will cause an IndexError.

07

Practical *args Examples

Calculating an Average

Average Calculator
def average(*numbers):

    if not numbers:
        return 0

    return sum(numbers) / len(numbers)

print(average(10, 20, 30))
print(average(80, 90, 70, 100))
Output
20.0
85.0

Building a Shopping Total

Shopping Cart
def shopping_total(*prices):
    return sum(prices)

total = shopping_total(1200, 850, 500, 300)

print(f"Total: Rs. {total}")
Output
Total: Rs. 2850
08

What Is **kwargs?

**kwargs allows a function to accept a variable number of keyword arguments.

Keyword arguments are passed using names such as name="Ali" or age=25.

Basic Example
def show_profile(**kwargs):
    print(kwargs)

show_profile(
    name="Ali",
    age=25,
    city="Multan"
)
Output
{'name': 'Ali', 'age': 25, 'city': 'Multan'}
Simple definition

**kwargs allows a function to accept a variable number of keyword arguments.

09

Why Use **kwargs?

Imagine building a function that creates a user profile. Different users may have different pieces of information.

Flexible Profile
def create_profile(**details):

    for key, value in details.items():
        print(f"{key}: {value}")

create_profile(
    name="Sara",
    age=24,
    profession="Designer",
    city="Lahore"
)
Output
name: Sara
age: 24
profession: Designer
city: Lahore

The caller can provide different named values without changing the function definition.

10

**kwargs Syntax

Syntax
def function_name(**kwargs):
    # use kwargs here
    pass

Just like args, the name kwargs is a convention. The important part is **.

Alternative Name
def show_data(**data):
    print(data)

show_data(name="Ali", age=30)
Output
{'name': 'Ali', 'age': 30}
11

**kwargs Is a Dictionary

Inside the function, keyword arguments are collected into a dictionary.

Dictionary Behavior
def show_data(**kwargs):

    print(kwargs)
    print(type(kwargs))

show_data(name="Ali", age=25)
Output
{'name': 'Ali', 'age': 25}
<class 'dict'>

Therefore, you can use dictionary methods such as .keys(), .values(), and .items().

12

Looping Through **kwargs

Loop Through Keyword Arguments
def display_info(**kwargs):

    for key, value in kwargs.items():
        print(f"{key}: {value}")

display_info(
    name="Ahmed",
    age=28,
    city="Islamabad"
)
Output
name: Ahmed
age: 28
city: Islamabad
13

*args vs **kwargs

*args

Collects extra positional arguments into a tuple.

**kwargs

Collects extra keyword arguments into a dictionary.

Quick Comparison
def example(*args, **kwargs):

    print("args:", args)
    print("kwargs:", kwargs)

example(
    10,
    20,
    30,
    name="Ali",
    city="Multan"
)
Output
args: (10, 20, 30)
kwargs: {'name': 'Ali', 'city': 'Multan'}
14

Using *args and **kwargs Together

A function can accept both types at the same time.

Both Together
def user_data(*args, **kwargs):

    print("Values:")

    for value in args:
        print(value)

    print("Details:")

    for key, value in kwargs.items():
        print(f"{key}: {value}")


user_data(
    "Python",
    "Programming",
    level="Beginner",
    duration="3 months"
)
Output
Values:
Python
Programming
Details:
level: Beginner
duration: 3 months
15

Normal Parameters with *args and **kwargs

You can combine normal parameters with variable arguments.

Normal + *args
def student(name, *marks):

    print("Student:", name)
    print("Marks:", marks)

student("Ali", 80, 75, 90)
Output
Student: Ali
Marks: (80, 75, 90)

Here, name receives the first argument, while the remaining positional arguments are collected by marks.

16

Argument Unpacking

The * and ** operators are also used when calling functions to unpack collections.

Unpacking a List

Using *
def add(a, b, c):
    return a + b + c

numbers = [10, 20, 30]

print(add(*numbers))
Output
60

*numbers unpacks the list into separate positional arguments.

Unpacking a Dictionary

Using **
def introduce(name, age):
    print(f"My name is {name} and I am {age} years old.")

person = {
    "name": "Sara",
    "age": 24
}

introduce(**person)
Output
My name is Sara and I am 24 years old.
Very important

In a function definition, *args and **kwargs collect arguments. During a function call, * and ** can unpack collections.

17

Real-World Examples

Example 1 — Product Price Calculator

E-Commerce Example
def calculate_cart(*prices, discount=0):

    subtotal = sum(prices)
    discount_amount = subtotal * discount
    final_total = subtotal - discount_amount

    return final_total

total = calculate_cart(
    1200,
    800,
    500,
    discount=0.10
)

print(f"Final Total: Rs. {total:.2f}")
Output
Final Total: Rs. 2250.00

Example 2 — Flexible User Registration

User System
def register_user(username, **details):

    print("Username:", username)

    for key, value in details.items():
        print(f"{key}: {value}")

register_user(
    "adnan123",
    email="user@example.com",
    city="Multan",
    role="Student"
)
Output
Username: adnan123
email: user@example.com
city: Multan
role: Student

Example 3 — Flexible Report Generator

Reporting Example
def create_report(*values, **settings):

    print("Values:", values)
    print("Settings:")

    for key, value in settings.items():
        print(f"{key}: {value}")


create_report(
    100,
    200,
    300,
    title="Sales Report",
    format="PDF",
    year=2026
)
Output
Values: (100, 200, 300)
Settings:
title: Sales Report
format: PDF
year: 2026
18

Common Mistakes

Mistake 1 — Confusing args with kwargs

Remember the difference

*args handles extra positional arguments, while **kwargs handles extra keyword arguments.

Mistake 2 — Forgetting the Star

Incorrect
def add(args):
    return sum(args)

This expects one argument, such as a list or tuple. It does not accept an arbitrary number of positional arguments.

For variable positional arguments, use:

Correct
def add(*args):
    return sum(args)

Mistake 3 — Accessing an Empty args Tuple

Potential Problem
def first_value(*args):
    return args[0]

print(first_value())

This causes an IndexError because there is no first item.

Mistake 4 — Treating kwargs Like a Tuple

kwargs is a dictionary, so use dictionary operations such as .items() and .get().

Mistake 5 — Thinking args and kwargs Are Special Names

The names args and kwargs are conventions. The operators * and ** are what give them their behavior.

19

Practice Exercises

Try solving each exercise yourself before checking a solution.

Exercise 1 — Sum Numbers

Create a function called total() that accepts any number of numbers using *args and returns their sum.

Exercise 2 — Find Maximum

Create a function that accepts any number of numeric arguments and returns the largest value.

Exercise 3 — Print Names

Create a function that accepts any number of names and prints each name on a separate line.

Exercise 4 — User Details

Create a function called show_user() that accepts any number of keyword arguments and displays them.

Exercise 5 — Product Information

Use **kwargs to create a product containing fields such as name, price, category, and stock.

Exercise 6 — Both Together

Create a function using both *args and **kwargs. Print each group separately.

Exercise 7 — Argument Unpacking

Create a list of three numbers and pass it to a three-parameter function using *.

20

Challenge — Flexible Sales Report

Build a flexible sales-report function that can accept any number of sales values and optional report settings.

Your Task

Create a function named sales_report().

It should:

  • Accept any number of sales amounts using *args.
  • Calculate the total sales.
  • Calculate the average sale.
  • Find the highest sale.
  • Accept optional settings using **kwargs.
  • Display those settings in the report.
Expected Usage
sales_report(
    12000,
    8500,
    15000,
    9200,
    title="Monthly Sales",
    month="August",
    currency="PKR"
)
Think like a developer

Use args for the collection of sales numbers and kwargs for flexible report configuration.

21

Quick Quiz

1

What does *args collect?

2

What type is args inside the function?

3

What does **kwargs collect?

4

What type is kwargs inside the function?

5

Which operator is used to unpack a list into positional arguments?

6

Which operator unpacks a dictionary into keyword arguments?

7

Are args and kwargs special Python keywords?

8

Can a function use both *args and **kwargs?

9

Which is normally used for optional named configuration values?

10

What does *numbers do when calling a function?

22

Lesson Summary

*args and **kwargs allow Python functions to accept flexible numbers of arguments.

  • *args collects extra positional arguments.
  • args is stored as a tuple.
  • **kwargs collects extra keyword arguments.
  • kwargs is stored as a dictionary.
  • *args is useful when the number of positional values is unknown.
  • **kwargs is useful when the number of named options is unknown.
  • Both can be used in the same function.
  • * can unpack lists, tuples, and other iterables into positional arguments.
  • ** can unpack dictionaries into keyword arguments.
Key takeaway

Think of *args as many positional values and **kwargs as many named values. Once this distinction becomes natural, flexible Python functions become much easier to design.

You've finished *args & **kwargs!

Mark this lesson complete when you are comfortable working with variable positional arguments, keyword arguments, and argument unpacking.