Python Argument Unpacking: A Complete Guide

Introduction: Python Argument Unpacking

Sometimes, a function needs values that are already in a list, tuple, or dictionary. The function, however, expects those values as separate arguments.

Without argument unpacking, you need to access the values from the collection and pass them one by one. This can become inconvenient when the collection contains several values.

Python solves this problem with Python Argument Unpacking. It lets a function call take values from a collection and pass them as separate arguments.

What Is Python Argument Unpacking?

Python Argument Unpacking is a feature in Python that lets you take values stored in an iterable or dictionary and pass them as separate arguments to a function call.

For example, suppose a function expects three positional arguments:

def add_numbers(a, b, c):
    return a + b + c

Normally, the values are passed separately:

add_numbers(10, 20, 30)

If the values are already stored in a collection, you can unpack them when calling the function instead of passing them one by one.

Python provides two unpacking operators:

  • * unpacks an iterable into positional arguments.
  • ** unpacks a dictionary into keyword arguments.

Let’s understand these two forms with simple examples.

* for Positional Arguments

Use * when an iterable contains values that you want to pass as positional arguments.

def introduce(name, age):
    print("Name:", name)
    print("Age:", age)

person = ["Alice", 25]

introduce(*person)


# Output:
Name: Alice
Age: 25

Explanation: The *person expression unpacks the list and passes "Alice" and 25 as separate positional arguments. Python assigns them to name and age in order.

For more detailed concepts and examples, see Unpacking Positional Arguments With *.

** for Keyword Arguments

Use ** when a dictionary contains values that you want to pass as keyword arguments.

def introduce(name, age):
    print("Name:", name)
    print("Age:", age)

person = {
    "name": "Alice",
    "age": 25
}

introduce(**person)


# Output:
Name: Alice
Age: 25

Explanation: The **person expression unpacks the dictionary into keyword arguments. The "name" key matches the name parameter, and the "age" key matches the age parameter.

For more detailed concepts and examples, see Unpacking Keyword Arguments With **.

In short, * passes unpacked values by position, while ** passes unpacked dictionary values by keyword.

Unpacking Positional Arguments With *: Argument Unpacking

A single asterisk (*) is used in Python argument unpacking to unpack an iterable into separate positional arguments when a function is called.

Before looking at specific examples, let’s see how * unpacks an iterable into positional arguments.

How * Unpacks an Iterable

An iterable contains values that Python can process one by one, such as a list, tuple, string, or set.

When * is used before an iterable in a function call, Python takes its values in order and passes them as separate positional arguments.

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

values = [10, 20, 30]

print(add(*values))


# Output:
60

Explanation: The call add(*values) passes the three values as if the call were written as add(10, 20, 30).

↑ Move to Section Top

Unpacking a List

A list is commonly used with * when its values need to be passed to a function as positional arguments.

Example

def display_product(name, price, quantity):
    print("Product:", name)
    print("Price:", price)
    print("Quantity:", quantity)

product = ["Laptop", 50000, 2]

display_product(*product)

# Output:
Product: Laptop
Price: 50000
Quantity: 2

Explanation: The list contains three values. Python passes them in order to name, price, and quantity.

↑ Move to Section Top

Unpacking a Tuple

A tuple works in the same way. Python takes each tuple value and passes it as a separate positional argument.

Example

def calculate_total(price, quantity):
    return price * quantity

order = (250, 4)

print(calculate_total(*order))


# Output:
1000

Explanation: Here, *order passes 250 and 4 as the two positional arguments.

↑ Move to Section Top

Unpacking Other Iterables

The * operator can unpack other iterables as well. For example, it can unpack a string into individual positional arguments.

Example

def show_letters(a, b, c):
    print(a)
    print(b)
    print(c)

letters = "ABC"

show_letters(*letters)


# Output:
A
B
C

Explanation: The string contains three characters, so *letters passes "A", "B", and "C" as separate positional arguments.

Note: The iterable must provide the right number of values for the function call.

↑ Move to Section Top

Using * With Regular Positional Arguments

You can combine an unpacked iterable with regular positional arguments in the same function call.

Example

def add_numbers(a, b, c, d):
    return a + b + c + d

values = [20, 30]

result = add_numbers(10, *values, 40)

print(result)


# Output:
100

Explanation: Here, 10 and 40 are regular positional arguments, while *values supplies 20 and 30.

The call passes the arguments in this order:

add_numbers(10, 20, 30, 40)

↑ Move to Section Top

Unpacking Keyword Arguments With **: Argument Unpacking

A double asterisk (**) unpacks a dictionary into separate keyword arguments when a function is called.

The following sections explain how ** unpacking works, how dictionary keys match parameters, and how unpacked and regular keyword arguments can be combined.

How ** Unpacks a Dictionary

A dictionary stores values using key-value pairs. When ** is placed before a dictionary in a function call, Python uses its keys as parameter names and its values as the corresponding arguments.

def introduce(name, age):
    print("Name:", name)
    print("Age:", age)

person = {
    "name": "Alice",
    "age": 25
}

introduce(**person)


# Output:
Name: Alice
Age: 25

Explanation: The **person expression unpacks the dictionary into the keyword arguments name="Alice" and age=25.

So, the following two function calls are equivalent:

introduce(**person)
introduce(name="Alice", age=25)

↑ Move to Section Top

Matching Dictionary Keys With Parameters

When a dictionary is unpacked with **, each key must match a parameter name that the function can accept.

Example

def calculate_total(price, quantity):
    return price * quantity

order = {
    "price": 250,
    "quantity": 4
}

print(calculate_total(**order))


# Output:
1000

Explanation: The key "price" matches the price parameter, and "quantity" matches the quantity parameter.

If a dictionary contains a key that does not match a parameter, Python raises a TypeError.

Example: Unexpected Keyword

def introduce(name, age):
    print(name, age)

person = {
    "name": "Alice",
    "city": "Delhi"
}

introduce(**person)


# Error:
TypeError: introduce() got an unexpected keyword argument 'city'

Explanation: The function accepts name and age, but the dictionary provides city instead of age. Python therefore cannot match the city key to a parameter.

↑ Move to Section Top

Using ** With Regular Keyword Arguments

An unpacked dictionary can be combined with regular keyword arguments in the same function call, as long as the resulting arguments are valid for the function.

Example

def introduce(name, age, city):
    print(name, age, city)

person = {
    "name": "Alice",
    "age": 25
}

introduce(**person, city="Delhi")


# Output:
Alice 25 Delhi

Explanation: The **person expression supplies name="Alice" and age=25, while city="Delhi" is supplied as a regular keyword argument.

The call is equivalent to:

introduce(
    name="Alice",
    age=25,
    city="Delhi"
)

The important rule is that the final function call must not contain the same keyword argument more than once.

↑ Move to Section Top

Related Argument Unpacking Topics

For more specific argument unpacking techniques, see:

Common Errors With Argument Unpacking

Python argument unpacking works correctly when the unpacking operator matches the type of argument the function expects. However, using the wrong operator, values, or keys can cause errors.

The following sections explain these common errors and how to avoid them.

  1. Using the Wrong Number of Values With *
  2. Using the Wrong Dictionary Keys With **
  3. Passing a Non-Iterable With *
  4. Providing the Same Keyword Argument More Than Once

Using the Wrong Number of Values With *

Rule: When an iterable is unpacked with *, it must provide the correct number of positional arguments for the function call.

def add_numbers(a, b, c):
    return a + b + c

values = [10, 20]

add_numbers(*values)


# Error:
TypeError: add_numbers() missing 1 required positional argument: 'c'

Explanation: The function expects three positional arguments, but the iterable provides only two values.

↑ Move to Section Top

Using the Wrong Dictionary Keys With **

Rule: When a dictionary is unpacked with **, its keys must match parameter names that the function can accept.

def introduce(name, age):
    print(name, age)

person = {
    "name": "Alice",
    "city": "Delhi"
}

introduce(**person)


# Error:
TypeError: introduce() got an unexpected keyword argument 'city'

Explanation: The function accepts name and age, but the dictionary contains the unexpected key "city".

↑ Move to Section Top

Passing a Non-Iterable With *

Rule: The * operator requires an iterable when it is used for argument unpacking.

def add_numbers(a, b):
    return a + b

value = 10

add_numbers(*value)


# Error:
TypeError: argument after * must be an iterable, not int

Explanation: An integer is not iterable, so Python cannot unpack value into positional arguments.

↑ Move to Section Top

Providing the Same Keyword Argument More Than Once

Rule: A keyword argument cannot be supplied more than once in the same function call.

def introduce(name, age):
    print(name, age)

person = {
    "name": "Alice"
}

introduce(**person, name="Bob")


# Error:
TypeError: got multiple values for argument 'name'

Explanation: The name argument is supplied once through **person and again as name="Bob". Python therefore raises a TypeError.

↑ Move to Section Top

Key Takeaways: Python Argument Unpacking

Here are the most important rules to remember when using argument unpacking in Python:

  • * unpacks an iterable into separate positional arguments.
  • ** unpacks a dictionary into separate keyword arguments.
  • The values produced by * must match the positional arguments accepted by the function.
  • The keys supplied by ** must match keyword parameters that the function can accept.
  • The same keyword argument cannot be supplied more than once in a function call.
  • * and ** can be combined with regular arguments when the resulting function call is valid.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut elit tellus, luctus nec ullamcorper mattis, pulvinar dapibus leo.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top