Iterating at Once with the Asterisk (*) – Unpacking in Data Science 2026
The asterisk (* and **) is a powerful Python feature for unpacking iterables and dictionaries. In data science, mastering unpacking helps you write cleaner, more concise, and more Pythonic code when working with lists, tuples, function arguments, and data structures.
TL;DR — Asterisk Usage
*– Unpacks iterables (lists, tuples, etc.)**– Unpacks dictionaries (keyword arguments)- Very useful in function calls, list creation, and data manipulation
1. Basic Unpacking with *
numbers = [10, 20, 30, 40]
# Unpacking into variables
a, b, *rest = numbers
print(a, b, rest) # 10 20 [30, 40]
# Using * in function calls
def calculate_total(*values):
return sum(values)
total = calculate_total(*numbers)
print(total)
2. Common Data Science Use Cases
import pandas as pd
# Create a small demo file so this example runs as-is
# (in your project, sales_data.csv is your real export)
import numpy as np
rng = np.random.default_rng(42)
n = 60
pd.DataFrame({
"order_id": range(1001, 1001 + n),
"order_date": pd.date_range("2026-01-01", periods=n, freq="3D"),
"customer_id": rng.integers(101, 121, n),
"customer_name": rng.choice([" ana", "ben ", "chen", "dana"], n),
"product_id": rng.integers(1, 9, n),
"region": rng.choice(["North", "South", "East", "West"], n),
"category": rng.choice(["Electronics", "Computers", "Books", "Home"], n),
"payment_method": rng.choice(["card", "cash", "wallet"], n),
"segment": rng.choice(["consumer", "business"], n),
"quantity": rng.integers(1, 6, n),
"amount": rng.uniform(50, 2500, n).round(2),
"discount": rng.choice([0.0, 0.05, 0.1, 0.2], n),
}).assign(
price=lambda d: (d["amount"] / d["quantity"]).round(2),
profit=lambda d: (d["amount"] * rng.uniform(0.05, 0.3, n)).round(2),
).assign(
ship_date=lambda d: d["order_date"] + pd.Timedelta(days=2),
status=lambda d: np.where(d["amount"] > 2000, "priority", "standard"),
).to_csv("sales_data.csv", index=False)
df = pd.read_csv("sales_data.csv")
# 1. Unpacking column names
cols = ["order_date", "customer_id", "amount", "region"]
date_col, id_col, *metric_cols = cols
# 2. Passing multiple arguments to a function
def train_model(*feature_columns):
print(f"Training with features: {feature_columns}")
train_model(*metric_cols)
# 3. Creating new lists with unpacking
new_features = ["profit", "margin", *metric_cols]
print(new_features)
3. Advanced Unpacking with ** (Dictionary Unpacking)
model_params = {
"n_estimators": 200,
"max_depth": 10,
"random_state": 42
}
# Unpacking dictionary as keyword arguments
def train_random_forest(**kwargs):
print("Training with parameters:")
for key, value in kwargs.items():
print(f" {key}: {value}")
train_random_forest(**model_params)
4. Best Practices in 2026
- Use
*to unpack iterables when calling functions or creating new lists - Use
**to unpack dictionaries as keyword arguments - Combine with
enumerate()andzip()for powerful one-liners - Use
*restto capture remaining elements when unpacking - Keep unpacking readable — avoid excessive complexity in one line
Unpacking with the Asterisk
A single asterisk unpacks an iterable into separate items. In a function call, print(*values) passes each item as its own argument. In an assignment, first, *rest = values collects the remaining items into a list.
Two asterisks do the same for dictionaries in function calls and dictionary literals: f(**options) passes key-value pairs as keyword arguments, and {**defaults, **overrides} merges dictionaries, with later keys winning.
These forms are concise ways to combine lists, pass configuration and split records without index arithmetic.
Worked Example: Splitting, Merging and Passing
We split a record, combine lists, merge settings and pass them to a function.
record = ["2026-01-05", "North", 120, 95, 130]
date, region, *daily_sales = record
print(date, region, daily_sales)
first, *_, last = daily_sales
print(first, last)
combined = [*daily_sales, *[110, 140]]
print(combined)
defaults = {"sep": ",", "decimal": "."}
overrides = {"sep": ";"}
settings = {**defaults, **overrides}
print(settings)
def describe(sep, decimal):
return f"sep={sep!r} decimal={decimal!r}"
print(describe(**settings))
The starred name always receives a list, even if it is empty. In the merged settings, the semicolon from overrides replaces the default comma because later keys win.
Common Mistakes
- Using more than one starred name in one assignment.
- Expecting a starred target to be a tuple rather than a list.
- Passing ** with keys that do not match parameter names.
- Forgetting that dictionary merge order decides which value wins.
Quick Summary
- *iterable unpacks items in calls and literals.
- first, *rest = seq splits sequences.
- **dict passes keyword arguments and merges dicts.
- Later keys win when merging.
Conclusion
The asterisk operators (* and **) are powerful tools for unpacking data in Python. In data science, they help you write cleaner code when passing column lists to functions, creating new feature sets, and handling configuration parameters. When used appropriately, unpacking makes your code more concise and Pythonic while maintaining readability.
Next steps:
- Review your current code and look for opportunities to use
*and**unpacking to simplify function calls and list/dict operations