The Unpacking Operator * in Lists and Dictionaries
As Python code evolves, combining data structures becomes a frequent task.
Lists grow, dictionaries merge, arguments get forwarded.
The unpacking operators * and ** exist to make these operations clearer, safer, and more expressive.
Unpacking lists and tuples with *
numbers = [3, 4, 5]
combined = [1, 2, *numbers]
print(combined)
# [1, 2, 3, 4, 5]
This avoids manual concatenation and keeps the intent obvious.
Unpacking dictionaries with **
defaults = {"host": "localhost", "port": 5432}
overrides = {"port": 5433}
config = {**defaults, **overrides}
print(config)
# {'host': 'localhost', 'port': 5433}
Later values override earlier ones, which makes configuration patterns very natural.
Unpacking in function calls
def connect(host, port):
print(host, port)
params = {"host": "localhost", "port": 5432}
connect(**params)
This is especially useful when passing data between layers or APIs.
Combining *args and **kwargs
def wrapper(*args, **kwargs):
return target(*args, **kwargs)
Unpacking plays a key role in decorators and wrappers.
A common mistake to avoid
Avoid overusing unpacking when it hides logic:
# Harder to understand
data = [*get_items(), *get_more_items(), *get_even_more()]
If the source of data matters, explicit steps can be clearer.
Conclusion
In real-world Python, unpacking operators help reduce noise and clarify intent.
Used thoughtfully, * and ** make code easier to read and reason about — not more magical.