Python match Statement
match Statement
The match statement is a pattern-based control structure that runs different blocks of code depending on the value (or shape) of an expression. It provides a cleaner and more readable alternative to long if–elif–else chains, especially when you compare one value against many possibilities.
Note: The
matchstatement is available in Python 3.10 and later. On older versions, it raises aSyntaxError. Check your version withpython --version.
Why Use match Instead of if–elif?
Consider a long chain of comparisons:
if command == "start":
...
elif command == "stop":
...
elif command == "pause":
...
The same variable is repeated in every condition. The match statement:
- Improves readability by naming the value once
- Reduces repetitive comparisons
- Clearly expresses the intent: "choose a branch based on this value"
- Is easier to extend — adding an option means adding one
case
Basic Syntax
match expression:
case value1:
# code block for value1
case value2:
# code block for value2
case _:
# default block when nothing else matches
Each case is followed by a pattern and a colon, and its block is indented beneath it.
How match Works
- The expression after
matchis evaluated once. - Each
casepattern is checked from top to bottom. - The first matching case runs.
- After that block runs, the
matchstatement ends — no other cases are checked. - The underscore
_is a wildcard that matches anything, so it acts as a default case.
Unlike the switch statement in languages such as C or Java, Python's match has no fall-through and needs no break — only one case ever runs.
Example: Menu Selection
choice = 2
match choice:
case 1:
print("Start Game")
case 2:
print("Load Game")
case 3:
print("Settings")
case 4:
print("Exit")
Expected output:
Load Game
choiceis evaluated once, giving2.case 1does not match;case 2does, so "Load Game" is printed.- Cases 3 and 4 are not evaluated.
If choice were 7, no case would match and nothing would be printed. To handle unexpected values, add a default case.
The Default Case Using _
The underscore _ matches any value. It works like the else clause of an if statement.
Example: Invalid Input Handler
rating = 8
match rating:
case 1:
print("Very Poor")
case 5:
print("Average")
case 10:
print("Excellent")
case _:
print("Unknown rating")
Expected output:
Unknown rating
8 does not match 1, 5, or 10, so the wildcard case runs.
The Wildcard Must Come Last
Because _ matches everything, any case placed after it could never run. Python detects this and refuses to run the code:
rating = 8
match rating:
case _:
print("Unknown rating")
case 10:
print("Excellent")
Output:
SyntaxError: wildcard makes remaining patterns unreachable
Always place case _: at the end.
Matching Multiple Values in One Case
Combine several values in one case with the pipe | operator, which means "or" inside a pattern.
Example: Traffic Signal Status
signal = "yellow"
match signal:
case "red":
print("Stop")
case "yellow" | "orange":
print("Prepare to stop")
case "green":
print("Go")
Expected output:
Prepare to stop
case "yellow" | "orange": matches if the value is either "yellow" or "orange".
Adding Conditions With Guards
A guard is an if condition attached to a case. The case runs only if the pattern matches and the guard is True.
Syntax
case pattern if condition:
Example: Discount Rules
user_type = "student"
purchase_amount = 1200
match user_type:
case "student" if purchase_amount > 1000:
print("Student discount applied")
case "member" if purchase_amount > 2000:
print("Premium member discount applied")
case _:
print("No discount available")
Expected output:
Student discount applied
How it works:
- The pattern
"student"matches the value ofuser_type. - The guard
purchase_amount > 1000is then checked:1200 > 1000isTrue. - Both conditions pass, so the first case runs.
If purchase_amount were 800, the pattern would still match, but the guard would fail. Python would then move on to the next case — and eventually to case _.
Capturing the Value for Use in a Guard
A plain name in a pattern captures the value into a variable. This is useful for range checks:
score = 77
match score:
case s if s >= 90:
print("Grade A")
case s if s >= 75:
print("Grade B")
case _:
print("Grade C")
Expected output:
Grade B
case s matches any value and stores it in s; the guard then tests it. For simple ranges like this, an if–elif chain is often equally clear.
Practical Example: HTTP Status Codes
status_code = 404
match status_code:
case 200:
print("Request successful")
case 400:
print("Bad request")
case 401 | 403:
print("Access denied")
case 404:
print("Resource not found")
case _:
print("Unknown status")
Expected output:
Resource not found
This is clearer and easier to maintain than a series of elif status_code == ... lines.
Beyond Simple Values: Structural Patterns
match is called structural pattern matching because it can also match the structure of data — such as the length and contents of a list, or the keys of a dictionary — and extract parts of it at the same time.
Matching a List
command = ["move", 10, 20]
match command:
case ["move", x, y]:
print(f"Moving to {x}, {y}")
case ["quit"]:
print("Quitting")
case _:
print("Unknown command")
Expected output:
Moving to 10, 20
The pattern ["move", x, y] matches a three-item sequence whose first item is "move", and it captures the other two items into x and y.
Matching a Dictionary
point = {"x": 1, "y": 2}
match point:
case {"x": 0, "y": 0}:
print("Origin")
case {"x": x, "y": y}:
print(f"Point at ({x}, {y})")
Expected output:
Point at (1, 2)
These advanced patterns are especially useful when processing commands, parsed text, or JSON data.
A Common Pitfall: Names Capture, They Do Not Compare
A bare variable name in a case is a capture pattern, not a comparison with that variable's value:
RED = "red"
color = "blue"
match color:
case RED:
print("Matched:", RED)
Expected output:
Matched: blue
case RED: did not compare color with "red". It matched any value and assigned it to a new variable RED, overwriting the original. To compare against a named constant, use a dotted name (such as Colors.RED from a class or enum) or a literal value like "red".
When to Use match
Use match when:
- You compare one value against many fixed options.
- The logic has many branches.
- You want to match the structure of lists, tuples, or dictionaries.
- Your project runs on Python 3.10 or later.
Prefer if–elif–else when:
- There is a simple two-way decision.
- Conditions involve complex Boolean expressions across several variables.
- Your code must run on Python versions earlier than 3.10.
Common Mistakes
| Mistake | Problem | ||
|---|---|---|---|
Using match on Python 3.9 or earlier | SyntaxError | ||
Placing case _: before other cases | SyntaxError: wildcard makes remaining patterns unreachable | ||
| Using a plain variable name to compare | The name captures any value instead of comparing | ||
| Expecting several cases to run | Only the first matching case runs | ||
Using or instead of ` | ` in a pattern | Use `case "a" | "b":` inside patterns |
Related Concepts
- Python elif Statement — the traditional way to check multiple conditions
- Python else Statement — default handling in
ifchains - Python Lists and Dictionaries — data structures you can match against