In Python function calls, there is a feature that allows you to pass data stored in a dictionary (dict) as “keyword arguments” all at once. This uses double asterisks **. It acts as the counterpart to *, which unpacks lists or tuples as positional arguments.
This article explains how to unpack dictionaries as keyword arguments and how to combine this with positional argument unpacking (*).
Unpacking Keyword Arguments (Dictionary Unpacking)
When calling a function, if you add ** before a dictionary, the dictionary’s “keys” are expanded as argument names and its “values” as argument values, and then passed to the function.
Syntax:
function_name(**dict_variable)
This is equivalent to writing function_name(key1=value1, key2=value2, ...).
Specific Usage Example
As an example, let’s use a function that displays request information for an API. This function requires three arguments: endpoint, method, and timeout.
def request_api(endpoint, method, timeout):
"""Function to display API request parameters"""
print(f"Endpoint: {endpoint}")
print(f"Method: {method}")
print(f"Timeout: {timeout} seconds")
print("--- Request Sent ---")
# When request settings are grouped in a dictionary
request_config = {
"method": "GET",
"timeout": 30,
"endpoint": "https://api.example.com/v1/users"
}
# Pass the dictionary unpacked by adding **
# The order of keys does not need to match the order of arguments
request_api(**request_config)
Output:
Endpoint: https://api.example.com/v1/users
Method: GET
Timeout: 30 seconds
--- Request Sent ---
Important Note: Keys Must Match Argument Names
When using this method, the dictionary keys must exactly match the function’s argument names. If the dictionary contains an argument name that does not exist in the function definition, a TypeError will occur.
invalid_config = {
"endpoint": "https://api.example.com",
"method": "POST",
"timeout": 30,
"retry": 3 # The function does not have a 'retry' argument
}
# This causes an error
# request_api(**invalid_config)
# TypeError: request_api() got an unexpected keyword argument 'retry'
(Note: If the function is defined to accept variable-length arguments with **kwargs, this error will not occur.)
Combining Positional (*) and Keyword (**) Unpacking
You can use list unpacking (*) and dictionary unpacking (**) simultaneously in a single function call. In this case, just like the definition order, you must write the positional arguments (*) first, followed by the keyword arguments (**).
Syntax:
function_name(*list_variable, **dict_variable)
Specific Usage Example
Let’s use a function that outputs server logs as an example. The mandatory information (timestamp, level) is managed in a list, and detailed attributes are managed in a dictionary.
def system_logger(timestamp, level, user=None, ip=None):
"""Function to output logs"""
print(f"[{timestamp}] {level}")
print(f" User: {user}")
print(f" IP: {ip}")
# Basic info (List)
base_info = ["2025-11-20 15:30:00", "WARNING"]
# Detailed info (Dictionary)
context = {
"user": "admin",
"ip": "192.168.10.5"
}
# Unpack and pass both the list and dictionary at the same time
system_logger(*base_info, **context)
Output:
[2025-11-20 15:30:00] WARNING
User: admin
IP: 192.168.10.5
The elements of base_info were assigned to timestamp and level, and the elements of context were assigned to user and ip.
Summary
- Adding
**before a dictionary when calling a function expands it as keyword arguments. - The dictionary keys must match the function’s argument names (keys must be strings).
- You can combine positional unpacking and keyword unpacking by writing
func(*list, **dict). - This technique is very effective when feeding dictionary data loaded from configuration files (like JSON) directly into processing functions.
