The asterisk in Python
* multiplies and ** raises to a power, so 2 ** 10 is 1024. In a function definition, *args collects extra positional arguments into a tuple and **kwargs collects extra keyword arguments into a dict. In a function call or a list or dict literal, the same symbols do the reverse: they unpack.
Every * in Python
| You write | It means |
|---|---|
a * b |
Multiply, or repeat a sequence: "ab" * 3 is "ababab" |
a ** b |
a to the power of b |
def f(*args) |
Collect extra positional arguments into a tuple |
def f(**kwargs) |
Collect extra keyword arguments into a dict |
def f(a, *, b) |
Everything after the bare * must be passed by keyword |
f(*items) |
Unpack a list or tuple into separate arguments |
f(**options) |
Unpack a dict into keyword arguments |
[*a, *b] |
Build a new list from the items of a and b |
{**a, **b} |
Merge two dicts; keys in b win |
first, *rest = items |
Put the leftovers in a list |
from module import * |
Import every public name |
except* ValueError: |
Handle part of an exception group (Python 3.11+) |
*args and **kwargs
In a function definition, a single * gathers any positional arguments that don't have their own parameter, and a double ** gathers any leftover keyword arguments:
def describe(name, *args, **kwargs):
print(name, args, kwargs)
describe("asterisk", 1, 2, color="red", size=12)
# asterisk (1, 2) {'color': 'red', 'size': 12}
The names args and kwargs are only a convention. *parts and **options work the same, because the asterisks do the work. The order is fixed: normal parameters, then *args, then keyword-only parameters, then **kwargs.
Unpacking in calls
In a call, * spreads a sequence into positional arguments and ** spreads a dict into keyword arguments:
point = (3, 4)
options = {"sep": " -> ", "end": "!\n"}
print(*point, **options)
# 3 -> 4!
This is how wrapper functions pass everything through unchanged: return func(*args, **kwargs).
Unpacking in assignments and literals
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last) # 1 [2, 3, 4] 5
combined = [*range(3), *"ab"]
print(combined) # [0, 1, 2, 'a', 'b']
defaults = {"color": "black", "size": 12}
custom = {"size": 16}
print({**defaults, **custom}) # {'color': 'black', 'size': 16}
A starred name in an assignment always gets a list, even when it catches nothing: a, *b = [1] leaves b as [].
The bare *: keyword-only arguments
A * on its own in a parameter list means "no more positional arguments after this point". The built-in sorted uses it, which is why key must be named:
sorted(["bb", "a"], key=len) # ['a', 'bb']
sorted(["bb", "a"], len) # TypeError: sorted expected 1 argument, got 2
Its partner is /: parameters before a / can only be passed by position. def f(a, /, b, *, c) makes a positional-only, b either, and c keyword-only.
** as the power operator
Two details trip people up:
print(-2 ** 2) # -4, because ** binds tighter than the minus sign
print((-2) ** 2) # 4
print(2 ** 3 ** 2) # 512, because ** groups right to left: 2 ** 9
For square roots, x ** 0.5 works, and math.sqrt(x) is clearer. pow(a, b, m) with a third argument computes powers modulo m far faster than a ** b % m for large numbers.
The sequence-repeat trap
* on a list repeats references, not copies. With nested lists, every row is the same object:
grid = [[]] * 3
grid[0].append("x")
print(grid) # [['x'], ['x'], ['x']]
grid = [[] for _ in range(3)]
grid[0].append("x")
print(grid) # [['x'], [], []]
from module import *
This imports every name in the module that doesn't start with an underscore, or exactly the names listed in its __all__. It's handy in the interactive shell and discouraged in real code by Python's style guide, PEP 8, because nobody reading the file can tell where a name came from.