Python Basics — Match-Case (Structural Pattern Matching)
Match-Case (Structural Pattern Matching)
Python 3.10 introduced match-case — a powerful way to branch based on the structure and value of data. Think of it as a smarter version of switch-case from other languages.
Requires Python 3.10+. Check your version:
python --version
Basic Syntax
command = "quit"
match command:
case "start":
print("Starting...")
case "stop":
print("Stopping...")
case "quit":
print("Goodbye!")
case _:
print(f"Unknown command: {command}")
Output:
Goodbye!
The _ (underscore) is the wildcard pattern — it matches anything, like else in an if chain.
Matching Literals
def http_status(code):
match code:
case 200:
return "OK"
case 301:
return "Moved Permanently"
case 404:
return "Not Found"
case 500:
return "Internal Server Error"
case _:
return f"Unknown status: {code}"
print(http_status(200)) # OK
print(http_status(404)) # Not Found
print(http_status(999)) # Unknown status: 999
Matching Multiple Values with |
day = "Saturday"
match day:
case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":
print("Weekday")
case "Saturday" | "Sunday":
print("Weekend!")
case _:
print("Invalid day")
Output:
Weekend!
Matching Sequences
Match-case can unpack lists and tuples:
point = (0, 5)
match point:
case (0, 0):
print("Origin")
case (x, 0):
print(f"On x-axis at x={x}")
case (0, y):
print(f"On y-axis at y={y}")
case (x, y):
print(f"Point at ({x}, {y})")
Output:
On y-axis at y=5
Notice how x and y are capture variables — they capture the actual values from the data.
Matching Mappings (Dictionaries)
action = {"type": "login", "user": "alice"}
match action:
case {"type": "login", "user": username}:
print(f"Logging in user: {username}")
case {"type": "logout", "user": username}:
print(f"Logging out user: {username}")
case {"type": "signup"}:
print("New user signup")
case _:
print("Unknown action")
Output:
Logging in user: alice
Dictionary matching checks that the specified keys exist — extra keys are allowed.
Guard Conditions
Add if clauses to add extra checks:
point = (3, 4)
match point:
case (x, y) if x == y:
print(f"On diagonal at ({x}, {y})")
case (x, y) if x > 0 and y > 0:
print(f"First quadrant: ({x}, {y})")
case (x, y):
print(f"Other: ({x}, {y})")
Output:
First quadrant: (3, 4)
Wildcard Pattern
The _ wildcard matches anything without binding a name:
data = [1, 2, 3, 4, 5]
match data:
case [first, *rest]:
print(f"First: {first}, Rest: {rest}")
Output:
First: 1, Rest: [2, 3, 4, 5]
# Star pattern with wildcard
match data:
case [first, _, _, _, last]:
print(f"First: {first}, Last: {last}")
Output:
First: 1, Last: 5
match-case vs if-elif
| Feature | match-case | if-elif |
|---|---|---|
| Simple value checks | Cleaner | Work fine |
| Pattern destructuring | Built-in | Requires manual unpacking |
| Multiple values | case A \| B: |
if x == A or x == B: |
| Guard conditions | case X if cond: |
Natural |
| Python version | 3.10+ | All versions |
| Complex expressions | Limited | Full flexibility |
Use match-case when:
- You’re checking a value against multiple fixed options
- You need to destructure data (sequences, mappings)
- You want clean, readable branching
Use if-elif when:
- You need complex conditions (ranges, function calls)
- You need to support Python < 3.10
- Logic doesn’t fit a pattern-matching model
Practical Example: Command Parser
def handle_command(parts):
match parts:
case ["quit"]:
return "Exiting..."
case ["hello", name]:
return f"Hello, {name}!"
case ["add", x, y]:
return f"Result: {int(x) + int(y)}"
case ["help"]:
return "Commands: quit, hello <name>, add <x> <y>"
case _:
return f"Unknown command: {' '.join(parts)}"
# Test
print(handle_command(["hello", "Alice"])) # Hello, Alice!
print(handle_command(["add", "3", "5"])) # Result: 8
print(handle_command(["quit"])) # Exiting...
print(handle_command(["fly"])) # Unknown command: fly
Summary
match-caseis Python 3.10+’s structural pattern matching- Use
_as the wildcard (default/catch-all) pattern - Match literals, sequences (lists/tuples), and mappings (dicts)
- Use
|to match multiple values in one case - Add guard conditions with
ifafter the pattern - Capture variables extract values from the matched data
- When in doubt,
if-elifworks everywhere and is more familiar
Next up: Truthy & Falsy Values →