match–case StatementTable of Contents
Toggle
match-case (Python 3.10+) lets you replace long if/elif chains with readable pattern matching.
Beyond simple values, it can match structures like lists, dicts, and even class objects.
match works only on Python 3.10+. Check with python --version.match_demo.py and run python match_demo.py.
match subject_expression:
case PATTERN_1:
# actions
case PATTERN_2:
# actions
case _:
# wildcard (default)
How it works: Python evaluates subject_expression once, then checks cases from top to bottom. The first match runs. There is no fall-through.
match–caseWe’ll map integers 0–6 to weekday names. Use _ as default for invalid input.
def weekday(n: int) -> str:
match n:
case 0: return "Monday"
case 1: return "Tuesday"
case 2: return "Wednesday"
case 3: return "Thursday"
case 4: return "Friday"
case 5: return "Saturday"
case 6: return "Sunday"
case _: return "Invalid day number"
print(weekday(3)) # Thursday
print(weekday(6)) # Sunday
print(weekday(7)) # Invalid day number
Use | to trigger the same action for multiple patterns.
def access(role: str) -> str:
match role:
case "admin" | "manager":
return "Full access"
case "guest":
return "Limited access"
case _:
return "No access"
print(access("manager")) # Full access
print(access("guest")) # Limited access
print(access("Ravi")) # No access
Attach if to a case to refine a match after capturing the value.
def classify(n: int) -> str:
match n:
case x if x < 0:
return "negative"
case 0:
return "zero"
case x if x % 2 == 0:
return "positive even"
case _:
return "positive odd"
Match list length and unpack items. *rest allows variable length.
def shape(items):
match items:
case [x, y]:
return f"two items: {x}, {y}"
case [first, *middle, last]:
return f"first={first}, last={last}, middle={middle}"
case []:
return "empty list"
case _:
return "unknown shape"
Match by keys; extra keys are allowed unless you use **rest.
def handle(payload: dict):
match payload:
case {"type": "user", "id": uid}:
return f"user id = {uid}"
case {"ok": True, **_}:
return "success"
case _:
return "ignored"
Unpack attributes via positional order (__match_args__) or keywords.
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
def locate(p: Point) -> str:
match p:
case Point(0, y):
return f"on Y axis at {y}"
case Point(x=_, y=0):
return "on X axis"
case Point(x, y):
return f"point at ({x}, {y})"
case _:
return "not a Point"
case x captures anything. To compare a constant, use a literal, an enum (e.g., Status.OK), or a guard (e.g., case x if x == LIMIT:)._ for “anything else”. Don’t reuse it inside the same match.**rest.if/elif.[date, sku, qty, price]; handle wrong shapes.type: "user.created" or "order.paid", extract fields and print messages.match-case is more powerful than switch because it supports patterns (shapes of data), not just single values.
