Match statements
The match statement, added in Python 3.10, compares a value against several patterns and runs the block for the first pattern that fits. It replaces long chains of if x == ...: elif x == ...: and can also pull values out of structured data.
Matching simple values
def http_status(code):
match code:
case 200:
return "OK"
case 404:
return "Not found"
case 500 | 502 | 503:
return "Server error"
case _:
return "Unknown"
print(http_status(200), http_status(503), http_status(418))- Each
caseis tested in order. |means "or".case _:is the wildcard that matches anything, likeelse.
Matching strings
command = "stop"
match command:
case "start":
print("Starting")
case "stop":
print("Stopping")
case _:
print("Unknown command")Capturing values
A bare name in a pattern captures whatever is there.
def describe(point):
match point:
case (0, 0):
return "origin"
case (x, 0):
return f"on the x axis at {x}"
case (0, y):
return f"on the y axis at {y}"
case (x, y):
return f"at ({x}, {y})"
print(describe((0, 0)))
print(describe((5, 0)))
print(describe((3, 4)))Matching lists
def summarise(items):
match items:
case []:
return "empty"
case [only]:
return f"one item: {only}"
case [first, *rest]:
return f"starts with {first}, then {len(rest)} more"
print(summarise([]))
print(summarise(["a"]))
print(summarise([1, 2, 3, 4]))Matching dictionaries
Only the listed keys need to be present; extra keys are ignored.
event = {"type": "click", "x": 10, "y": 20}
match event:
case {"type": "click", "x": x, "y": y}:
print(f"Clicked at {x}, {y}")
case {"type": "key", "key": k}:
print(f"Pressed {k}")Guards
Add if to a case for an extra condition.
def bucket(n):
match n:
case int() if n < 0:
return "negative"
case int() if n == 0:
return "zero"
case int():
return "positive"
case _:
return "not an integer"
print(bucket(-3), bucket(0), bucket(9), bucket("x"))int() in a pattern checks the type without calling anything.
When to use match
Reach for match when you are branching on the shape of data: tuples, lists, dictionaries, or objects with attributes. For a single comparison a plain if is still clearer.
Practice
- Write a
matchthat converts the strings "mon", "tue" and "wed" to full day names and returns "invalid" otherwise. - Write a function that accepts a tuple describing a shape, such as
("circle", 5)or("rect", 3, 4), and returns its area usingmatch.
