Python Multiple Argument Unpacking: Using * and ** Together

Introduction: Python Multiple Argument Unpacking

Sometimes the values needed by a function are stored in more than one list, tuple, or dictionary. Passing every value separately can make the function call longer, especially when the values are already grouped into different collections.

Python provides a simpler way to handle this situation. Python multiple argument unpacking lets you unpack more than one collection in the same function call using *, **, or both operators together.

Definition: Multiple argument unpacking means using two or more unpacking expressions in one function call to expand values from multiple collections into positional or keyword arguments.

The following sections show how multiple unpacking works with sequences, dictionaries and both unpacking operators together.

Unpacking Multiple Sequences

When positional arguments are stored in separate collections, you can use * multiple times in the same function call. Python expands each iterable into positional arguments in the order the unpacking expressions appear.

Using * Multiple Times

Suppose the values needed by a function are divided between two lists. Instead of combining the lists first, you can unpack both lists directly in the function call.

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

first = [10, 20]
second = [30, 40]

print(add(*first, *second))


# Output:
100

Explanation: The *first expression supplies 10 and 20, while *second supplies 30 and 40. Python passes all four values as positional arguments.

The call is equivalent to:

add(10, 20, 30, 40)

Using Different Iterable Types

The unpacking expressions do not have to use the same iterable type. For example, Python multiple argument unpacking can unpack a list and a tuple in the same function call.

def show(a, b, c, d):
    print(a, b, c, d)

numbers = [10, 20]
values = (30, 40)

show(*numbers, *values)


# Output:
10 20 30 40

Explanation: *numbers supplies the first two positional arguments, and *values supplies the next two. Python processes the unpacked values in the order they appear in the function call.

↑ Move to Top

Unpacking Multiple Dictionaries

When keyword arguments are stored in separate dictionaries, you can use ** multiple times in the same function call. Each dictionary supplies keyword arguments to the function.

Using ** Multiple Times

For example, personal information and location information can be stored in separate dictionaries and unpacked into one function call.

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

person = {
    "name": "Alice"
}

details = {
    "age": 25,
    "city": "Delhi"
}

introduce(**person, **details)

# Output:
Alice 25 Delhi

Explanation: The **person expression supplies name="Alice", while **details supplies age=25 and city="Delhi".

The function call is equivalent to:

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

Python multiple argument unpacking also has an important restriction when dictionaries are involved: the same keyword cannot be supplied more than once in a function call.

Duplicate Keyword Restriction

If two dictionaries contain the same key and both are unpacked with **, Python cannot assign two different values to the same keyword argument.

Example: Duplicate Keyword

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

first = {
    "name": "Alice"
}

second = {
    "name": "Bob",
    "age": 25
}

introduce(**first, **second)


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

Explanation: The first dictionary provides name="Alice", while the second provides name="Bob". Because the name keyword is supplied twice, Python raises a TypeError.

↑ Move to Top

Using * and ** Multiple Times

Python multiple argument unpacking can use several * expressions and ** expressions in the same function call. The resulting positional and keyword arguments must still match the parameters that the function can accept.

Combining Multiple * Unpacking Operations

You can unpack multiple sequences to supply positional arguments to one function.

def show(name, age, city, country):
    print(name, age, city, country)

first = ["Alice", 25]
second = ["Delhi", "India"]

show(*first, *second)


# Output:
Alice 25 Delhi India

Explanation: *first supplies "Alice" and 25, while *second supplies "Delhi" and "India".

Combining * and **

You can also combine multiple positional unpacking operations with keyword unpacking in the same function call.

def show(name, age, city, country):
    print(name, age, city, country)

first = ["Alice", 25]
second = ["Delhi"]

location = {
    "country": "India"
}

show(*first, *second, **location)

# Output:
Alice 25 Delhi India

Explanation: *first supplies "Alice" and 25, *second supplies "Delhi", and **location supplies country="India".

Equivalent Function Call

After unpacking, the function receives the same arguments as it would receive from a regular function call:

show("Alice", 25, "Delhi", country="India")

The difference is that the values remain stored in their original collections instead of being written out individually.

Practical Use of Multiple Unpacking

Multiple unpacking is useful when related values come from separate collections but need to be passed to the same function. For example, personal details can be stored in one list, location information in another, and additional named values in a dictionary.

def display(name, age, city, country):
    print(name, age, city, country)

personal = ["Alice", 25]
location = ["Delhi"]
extra = {
    "country": "India"
}

display(*personal, *location, **extra)


# Output:
Alice 25 Delhi India

Here, each collection keeps its own data, while the function call combines their values when the arguments are needed.

↑ Move to Top

Common Mistakes in Python Multiple Argument Unpacking

Python multiple argument unpacking can cause errors when the combined unpacked arguments do not form a valid function call. The most common problems involve duplicate keywords or an incorrect number or combination of arguments.

The following sections cover the most common mistakes when using multiple unpacking expressions.

  1. Duplicate Keywords
  2. Too Many Positional Arguments
  3. Too Few Positional Arguments
  4. Duplicate Positional and Keyword Arguments

1. Duplicate Keywords

When using ** multiple times, make sure that the dictionaries do not provide the same keyword.

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

first = {
    "name": "Alice"
}

second = {
    "name": "Bob",
    "age": 25
}

introduce(**first, **second)


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

Explanation: The first dictionary provides name="Alice", while the second provides name="Bob". Because the same keyword is supplied twice, Python raises a TypeError.

# Correct Example
def introduce(name, age):
    print(name, age)

first = {
    "name": "Alice"
}

second = {
    "age": 25
}

introduce(**first, **second)


# Output:
Alice 25

Explanation: Each dictionary provides a different keyword, so Python can combine both unpacked dictionaries into one valid function call.

↑ Move to Section Top

2. Too Many Positional Arguments

When using * multiple times, each iterable contributes its values as positional arguments. If the combined values exceed the number of positional arguments the function accepts, Python raises a TypeError.

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

first = [10]
second = [20, 30]

add(*first, *second)


# Error:
TypeError: add() takes 2 positional arguments but 3 were given

Explanation: The two unpacking expressions provide three positional arguments, but the function accepts only two.

# Correct Example
def add(a, b):
    return a + b

first = [10]
second = [20]

print(add(*first, *second))


# Output:
30

Explanation: The two unpacking expressions provide exactly two positional arguments, which match the two parameters accepted by the function.

↑ Move to Section Top

3. Too Few Positional Arguments

When multiple iterables are unpacked with *, their combined values must provide enough positional arguments for the function.

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

first = [10]
second = [20]

add(*first, *second)


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

Explanation: The two unpacking expressions provide only two positional arguments, but the function requires three.

# Correct Example
def add(a, b, c):
    return a + b + c

first = [10]
second = [20, 30]

print(add(*first, *second))


# Output:
60

Explanation: The two unpacking expressions provide three positional arguments, which match the three parameters accepted by the function.

↑ Move to Section Top

4. Duplicate Positional and Keyword Arguments

When * and ** are combined, the same parameter cannot receive a value from both a positional argument and a keyword argument.

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

person = {
    "name": "Alice"
}

introduce("Bob", **person)

# Error:
TypeError: introduce() got multiple values for argument 'name'

Explanation: The positional argument "Bob" supplies name, while **person supplies name="Alice". Python therefore receives two values for the same parameter.

# Correct Example
def introduce(name, age):
    print(name, age)

person = {
    "age": 25
}

introduce("Bob", **person)


# Output:
Bob 25

Explanation: The positional argument "Bob" supplies name, while **person supplies age=25. Each parameter receives one value, so the function call is valid.

↑ Move to Section Top

Key Takeaways: Multiple Argument Unpacking

Here are the key points to remember about Python multiple argument unpacking:

  • You can use * multiple times to unpack multiple iterables into positional arguments.
  • You can use ** multiple times to unpack multiple dictionaries into keyword arguments.
  • You can combine multiple * and ** operations in one function call.
  • Multiple unpacking preserves the order of positional values as they appear in the function call.
  • Dictionary unpacking cannot provide the same keyword more than once.
  • The final set of unpacked arguments must form a valid function call for the target function.

Leave a Comment

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

Scroll to Top