Recommended Free Tools
Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
* and ** expand values in different ways. In a function call, *iterable turns each item into a positional argument, while **mapping turns each key-value pair into a keyword argument. The same notation also appears in assignments, list displays and dictionary displays, where it has related but distinct behavior.
What the operators mean
Think of unpacking as removing one container layer. A list, tuple or other iterable can be spread into individual values with *. A dictionary or other mapping can be spread into named entries with **. The surrounding Python construct determines what those values become.
| Context | Syntax | Operand required | Result |
|---|---|---|---|
| Function call | func(*items) |
Iterable | Separate positional arguments |
| Function call | func(**options) |
Mapping | Keyword arguments |
| Assignment | first, *rest = values |
Iterable | rest receives a list of remaining items |
| List display | [*items] |
Iterable | Items inserted into a new list |
| Dictionary display | {**options} |
Mapping | Entries inserted into a new dictionary |
The Python tutorial documents argument-list unpacking and display forms at docs.python.org/3/tutorial/controlflow.html, while the language reference specifies expression and dictionary-display rules at docs.python.org/3/reference/expressions.html.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Unpack positional arguments with *
Calling a function from a list or tuple
Use a single star when the function expects separate positional parameters but your values are already grouped in an iterable.
#1 Best Overall
def make_point(x, y):
return {"x": x, "y": y}
coords = (3, 8)
point = make_point(*coords)
print(point) # {'x': 3, 'y': 8}
make_point(*coords) is equivalent to make_point(3, 8). Python iterates over coords and supplies each item in order.
Matching arity matters
The number of unpacked values must fit the callable’s positional parameters, subject to its default and variadic arguments.
def add(a, b):
return a + b
values = [2, 4]
print(add(*values)) # 6
# add([2, 4]) # TypeError: one list argument, not two numbers
# add(*[1, 2, 3]) # TypeError: too many positional arguments
An integer is not iterable, so add(*5) raises TypeError: argument after * must be an iterable, not int. Wrap a single value in a tuple or list if that is what the API requires.
Combining ordinary and unpacked arguments
def report(name, *scores):
return name, scores
scores = [91, 88, 95]
print(report("Mina", *scores)) # ('Mina', (91, 88, 95))
Regular positional arguments and starred iterables can be mixed. Evaluation follows the call expression’s order.
Unpack keyword arguments with **
Passing dictionary keys as parameter names
Use two stars when a mapping’s keys correspond to the function’s keyword parameters.
Rank #2
def parrot(voltage, state="a stiff", action="voom"):
print(voltage, state, action)
options = {"voltage": "four million", "state": "stable"}
parrot(**options)
# four million stable voom
This is equivalent to parrot(voltage="four million", state="stable"). Every key must be a valid keyword accepted by the function. A misspelled key produces an unexpected-keyword TypeError.
Combining positional and keyword expansion
def connect(host, port, secure=False):
return host, port, secure
address = ("example.com", 443)
flags = {"secure": True}
print(connect(*address, **flags))
Do not provide the same parameter twice. For example, connect("example.com", *[443], port=8443) raises a multiple-values error for port.
Free tools Windows power users keep installed
One-click scans. No signup required.
Definitions versus calls
The spelling looks similar in a function definition but reverses the operation. In a definition, *args collects extra positional arguments into a tuple and **kwargs collects extra keyword arguments into a dictionary.
def log_event(event, *args, **kwargs):
print(event)
print(args) # tuple of extra positional values
print(kwargs) # dictionary of extra named values
log_event("upload", "image.png", retry=True)
At a call site, * and ** expand existing containers; in a definition they collect arguments supplied by the caller.
Starred assignment targets
Extended iterable unpacking lets one assignment target absorb any number of middle items. The starred target is always a list, even when the source is a tuple or generator.
values = [10, 20, 30, 40]
first, *middle, last = values
print(first) # 10
print(middle) # [20, 30]
print(last) # 40
Beginning, middle and end forms
*start, last = [1, 2, 3]
# start == [1, 2], last == 3
first, *rest = [1, 2, 3]
# first == 1, rest == [2, 3]
first, *nothing, last = [7, 9]
# nothing == []
There can be only one starred target in a single unpacking assignment because Python must know how to divide the remaining items. The non-starred targets still require enough values; otherwise Python raises ValueError.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Any iterable can be unpacked
def numbers():
yield 4
yield 5
yield 6
first, *rest = numbers()
print(first, rest) # 4 [5, 6]
The iterable is consumed to create the list for the starred target. Be careful with large or infinite iterators: collecting the remainder can use substantial memory or never finish.
Unpacking in list displays
A starred expression inside a list contributes each item to the new list rather than adding the source iterable as one nested element.
items = ["start", *range(3), "end"]
print(items) # ['start', 0, 1, 2, 'end']
left = [1, 2]
right = [3, 4]
combined = [*left, *right]
This is useful for concatenating iterables while keeping fixed values visible. The operand must be iterable; [*42] raises TypeError. Unlike left + right, display unpacking also works naturally with generators and other iterable types.
Unpacking in dictionary displays
Two stars in a dictionary display copy key-value pairs into a new dictionary.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchdefaults = {"color": "blue", "count": 8}
overrides = {"color": "yellow"}
combined = {**defaults, **overrides}
print(combined) # {'color': 'yellow', 'count': 8}
Later entries win
When keys collide, the entry appearing later in the display replaces the earlier value. This makes the defaults-then-overrides pattern explicit.
base = {"timeout": 10, "retries": 2}
per_request = {"timeout": 30}
config = {**base, **per_request}
The operation creates a new dictionary; it does not mutate either source. The operand must be a mapping, so {**[('a', 1)]} fails even though the list contains pairs. Use dict([('a', 1)]) first when necessary.
Multiple mappings and ordinary entries
user = {"name": "Ari"}
record = {"id": 17, **user, "active": True}
Dictionary-display unpacking was added in Python 3.5 through the work proposed by PEP 448, as described in the language reference. It is available in supported Python 3 versions.
Choosing the right form
| Question | Use | Example |
|---|---|---|
| Does a callable need positional values? | * at the call site |
range(*limits) |
| Does a callable need named values? | ** at the call site |
request(**params) |
| Do you need the first/last item plus the remainder? | Starred assignment target | head, *tail = data |
| Do you need one flat list? | * in a list display |
[*a, *b] |
| Do you need defaults overridden? | ** in a dictionary display |
{**defaults, **custom} |
Common errors and fixes
- “Argument after * must be an iterable.” The value is not iterable. Pass a list, tuple, string or other iterable, or remove the star for a single scalar.
- “Argument after ** must be a mapping.” Use a dictionary or mapping object, not a list of pairs or a scalar.
- Unexpected keyword argument. Check that every dictionary key exactly matches a parameter name and that the function accepts it.
- Multiple values for an argument. A parameter was supplied positionally and by keyword. Supply it once.
- Not enough or too many values to unpack. Count fixed assignment targets and remember that only one starred target may absorb the remainder.
- Unexpected overwrite in a merged dictionary. Inspect display order; later duplicate keys always win.
Performance, evaluation and compatibility
Unpacking is generally a clarity feature, not a promise of zero-copy behavior. A list display and dictionary display create new containers, and a starred assignment creates a new list for its remainder. Function-call expansion may iterate through the operand before invocation. For very large data, consider whether a streaming interface or direct iteration is more appropriate.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesExtended iterable unpacking arrived in Python 3.0 under PEP 3132; the Python 3.0 notes record that the collected target is always a list: docs.python.org/3.10/whatsnew/3.0.html. Dictionary-display unpacking requires Python 3.5 or newer. These operators are separate grammar features from typing syntax, so consult version-specific typing documentation when stars appear in annotations.
Best Value
Or skip the browser setup
If you are generating documentation or other visual assets from web pages, ScreenshotNeo provides a single-call screenshot API and MCP server. It accepts cookie and consent banners before capture, removes more than 60 known consent platforms plus newsletter popups and chat widgets, and bills only clean shots. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed; each response identifies the result with X-Page-Verdict and X-Billed headers.
For a quick capture, see the ScreenshotNeo API documentation:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request in Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
And in Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. Every plan includes features such as full-page and selector capture, device presets, custom CSS and JavaScript, waits, request blocking, headers and cookies, geolocation, PDF options, caching, signed links, asynchronous jobs and bulk capture of up to 100 URLs per call. The Free plan includes 1,000 screenshots each month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
FAQ
Can I use both * and ** in one call?
Yes. Use * for positional values and ** for keyword values, provided they do not assign the same parameter twice.
Does starred assignment preserve the source type?
No. The starred target is always a list, regardless of whether the source is a tuple, list, string or generator.
Do dictionary unpacking operations modify the original dictionaries?
No. A dictionary display creates a new dictionary; duplicate keys are resolved according to display order.
Frequently Asked Questions
Can a function call unpack a set with *?
Yes, because a set is iterable, but its iteration order is not a reliable positional order. Use an ordered sequence when argument positions matter.
Why does ** accept dictionaries but not ordinary lists?
Keyword expansion needs key-value pairs addressed by parameter names, so Python requires a mapping. Convert suitable pair data to a dictionary first.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

