The match statement compares a value with a series of patterns and runs
the block of the first that matches, taking the value apart as it goes. It is called
structural pattern matching (Python 3.10, Language Reference 8.6). PEP 634 is
the specification, PEP 635 gives the reasons for the design, and PEP 636 is a
tutorial.
Syntax
match_stmt: 'match' subject_expr ":" NEWLINE INDENT case_block+ DEDENT
case_block: 'case' patterns [guard] ":" suite
guard: "if" assignment_expression
match, case and _ are
soft keywords, so they
remain usable as names elsewhere. A match statement needs at least one
case. A subject with a comma is a tuple, as in
match a, b:.
def describe(command):
match command:
case []:
return "nothing"
case ["go", direction]:
return f"going {direction}"
case ["drop", *items]:
return f"dropping {len(items)} things"
case {"type": "click", "pos": (x, y)}:
return f"click at {x}, {y}"
case int(n) if n > 0:
return f"positive number {n}"
case _:
return "unknown"
How it runs
- The subject is evaluated once.
- The patterns are tried in order. There is no fall-through: only one block runs.
- When a pattern matches, its capture names are bound. If a guard is present it is then evaluated, and a false guard moves on to the next case.
- The block of the matching case runs, and the statement ends.
- If no case matches, nothing happens and no exception is raised.
Names bound by a successful match stay bound after the statement. A pattern that fails partway may or may not leave some of its names bound, and a program should not depend on either behaviour.
Patterns
| Pattern | Example | Matches when | Binds |
|---|---|---|---|
| Literal | 200, "on", None | Equal to the literal, or identical for None, True, False | Nothing |
| Capture | x | Always | x |
| Wildcard | _ | Always | Nothing |
| Value | Color.RED | Equal to the dotted name's value | Nothing |
| Group | (p) | p matches | As p |
| Sequence | [a, *b, c] | A sequence of the right length | Names inside |
| Mapping | {"k": v, **rest} | A mapping with those keys | Names inside |
| Class | Point(x=0, y=y) | An instance whose attributes match | Names inside |
| OR | p | q | Any alternative matches | The same names in each |
| AS | p as x | p matches | x, and names in p |
Literal patterns
literal_pattern: signed_number | signed_number "+" NUMBER | signed_number "-" NUMBER
| strings | "None" | "True" | "False"
signed_number: ["+" | "-"] NUMBER
Numbers and strings are compared with ==. The singletons
None, True and False are compared with
is. The + and - forms between numbers write a
complex number, as in 3 + 4j. A leading + is allowed since
Python 3.15. An f-string is not a literal pattern.
Capture and wildcard patterns
A bare name is a capture pattern: it always matches and binds the name. A
name can appear only once in a pattern. _ is the wildcard,
which also always matches and binds nothing, so it can appear many times.
A bare name is never compared with an existing variable. To compare with a value, use a dotted name or a guard.
RED = "#ff0000"
match colour:
case RED: # binds a new name RED; matches everything
...
Value patterns
A dotted name, such as http.HTTPStatus.OK, is looked up normally and
compared with ==.
Group patterns
Parentheses around one pattern only control grouping. (1 | 2) as x
groups, and (x) is a capture. A comma makes a
sequence pattern instead.
Sequence patterns
[a, b], (a, b) and a, b are all the same
pattern. It matches a sequence with exactly that many items, each matching its
subpattern. A star takes any number of items, and a sequence pattern can have at most
one:
match data:
case [first, *middle, last]:
... # two or more items; middle is a list
case [_, _]:
... # exactly two
case [*_]:
... # any sequence
The subject must be a sequence, but str, bytes and
bytearray never match a sequence pattern.
Mapping patterns
mapping_pattern: "{" [items_pattern] "}"
key_value_pattern: (literal_pattern | value_pattern) ":" pattern | double_star_pattern
double_star_pattern: "**" capture_pattern
Each key must be present in the subject, and the value must match the subpattern.
Extra keys are ignored, so {} matches any mapping. **rest
collects the other items and must come last. **_ is not allowed. A
repeated literal key is a SyntaxError.
Class patterns
class_pattern: name_or_attr "(" [pattern_arguments ","?] ")"
pattern_arguments: positional_patterns ["," keyword_patterns] | keyword_patterns
The subject must be an instance of the class, checked with
isinstance. Each keyword argument then names an attribute that must
exist and match:
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
def where(p):
match p:
case Point(x=0, y=0):
return "origin"
case Point(x, y) if x == y:
return f"diagonal at {x}"
case Point():
return "somewhere"
__match_args__ automaticallyPositional arguments use the class attribute __match_args__, a tuple of
attribute names. With too many positional patterns, TypeError is raised
at run time, and C(1, y=2, y=3) is a SyntaxError.
Some built-in types treat a single positional subpattern as the whole value:
bool, bytearray, bytes, dict,
float, frozendict, frozenset,
int, list, set, str and
tuple. int(n) binds the integer itself. Because
bool is a subclass of int, int() also matches
True.
OR patterns
p | q tries each alternative from left to right. Every alternative must
bind the same names, and only the last may be
irrefutable.
AS patterns
p as name binds the whole value matched by p to
name: case [1, 2] | [3, 4] as pair:.
Guards
A guard, if condition, runs after the pattern matches and can use the
names it bound (8.6.2). If the guard is false, the next case is tried.
Irrefutable cases
An irrefutable case has no guard and a pattern that always succeeds (8.6.3).
These are capture patterns, wildcard patterns, an AS pattern on an irrefutable pattern,
an OR pattern with an irrefutable alternative, and a group holding an irrefutable
pattern. A match statement can have at most one, and it must be last. Otherwise the
compiler raises SyntaxError, because the later cases could never run. A
final case _: is the usual default.