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.
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.
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.
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.
- Duplicate Keywords
- Too Many Positional Arguments
- Too Few Positional Arguments
- 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.
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.
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 Exampledef 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.
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 Exampledef 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.
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.
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.
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.