Advertisement
🔀 Control Flow

Python Match Case – Pattern Matching (Python 3.10+)

Python 3.10 introduced the match statement — Python's version of switch/case found in other languages, but far more powerful. It supports structural pattern matching: matching against values, types, sequences, mappings, and object attributes. It requires Python 3.10 or newer.

⏱️ 20 min read 🎯 Intermediate 📅 Updated 2026

Basic Match-Case Syntax

The match statement compares a value against multiple patterns. The first matching pattern executes its block. The case _: is the wildcard (matches anything — like "else").

Python
def describe_http_status(status):
    match status:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 500:
            return "Server Error"
        case _:              # wildcard - matches anything
            return f"Unknown status: {status}"

print(describe_http_status(200))
print(describe_http_status(404))
print(describe_http_status(999))
▶ Output
OK Not Found Unknown status: 999

OR Patterns – Multiple Values

Use | to match multiple values in a single case.

Python
def day_type(day):
    match day:
        case "Monday" | "Tuesday" | "Wednesday" | "Thursday" | "Friday":
            return "Weekday"
        case "Saturday" | "Sunday":
            return "Weekend"
        case _:
            return "Invalid day"

print(day_type("Monday"))    # Weekday
print(day_type("Saturday"))  # Weekend
▶ Output
Weekday Weekend
Advertisement

Guard Conditions with if

Add an if guard to a case for additional conditions.

Python
def classify(value):
    match value:
        case x if x < 0:
            return f"{x} is negative"
        case 0:
            return "zero"
        case x if x > 0 and x <= 100:
            return f"{x} is between 1 and 100"
        case _:
            return f"{value} is over 100"

print(classify(-5))
print(classify(0))
print(classify(42))
▶ Output
-5 is negative zero 42 is between 1 and 100

Matching Sequences and Dicts

Match can destructure lists, tuples, and dicts directly.

Python
# Match sequences (lists/tuples)
def describe_point(point):
    match point:
        case [0, 0]:
            return "Origin"
        case [x, 0]:
            return f"On X-axis at {x}"
        case [0, y]:
            return f"On Y-axis at {y}"
        case [x, y]:
            return f"Point at ({x}, {y})"

print(describe_point([0, 0]))
print(describe_point([3, 0]))
print(describe_point([4, 5]))
▶ Output
Origin On X-axis at 3 Point at (4, 5)

match/case: Structural Pattern Matching, Not Just a Switch

Python 3.10's match looks like a switch, but it does far more — it can destructure data and bind variables while matching, which a chain of if/elif can't do cleanly.

def handle(command):
    match command.split():
        case ["go", direction]:            # unpacks a 2-item list, binds direction
            return f"Moving {direction}"
        case ["drop", *items]:             # captures the rest
            return f"Dropping {items}"
        case ["quit" | "exit"]:            # OR pattern
            return "Bye"
        case _:                            # wildcard = default
            return "Unknown"

Match on shape, with guards

match point:
    case (0, 0):              return "origin"
    case (x, 0):              return f"on x-axis at {x}"     # binds x
    case (x, y) if x == y:    return "diagonal"              # guard condition
    case Point(x=px, y=py):   return f"point {px},{py}"      # class pattern

Key distinction: a plain switch only compares equality; match matches structure — list/tuple shapes, dict keys, class attributes — and captures parts into variables in the same step. Gotcha: a bare name like case x: is a capture (matches anything, binds x), not a comparison — to match against a constant, use a dotted name (case Color.RED) or a literal. Reach for it when branching on the shape of data; simple value checks are still fine as if/elif.

🏋️ Practical Exercise

Practice structural pattern matching (Python 3.10+):

  1. Write a match that maps HTTP status codes (200, 404, 500) to messages, with a wildcard _ default.
  2. Use an OR pattern (case 401 | 403:) to handle multiple values in one branch.
  3. Add a guard condition (case n if n > 0) to a branch.
  4. Match a small tuple like (x, y) and unpack its parts inside the case.

🔥 Challenge Exercise

Build a tiny command parser. Read commands such as "go north", "take key", or "quit", split them into words, and use match with sequence patterns (e.g. case ["go", direction]:) to handle each command, capturing the variable parts. Add a guard so only valid directions are accepted, and a wildcard branch for unknown commands.

📋 Summary

  • match-case was added in Python 3.10 for structural pattern matching.
  • It compares a subject against patterns, not just values — it can destructure sequences, mappings, and objects.
  • OR patterns (case a | b:) let several values share one branch.
  • Guard conditions (case x if cond:) add an extra boolean test to a pattern.
  • The wildcard _ matches anything and acts as the default case.
  • For simple value checks, if/elif is fine; match shines when unpacking complex shapes.

Interview Questions on Match-Case

  • What is the match-case statement and in which Python version was it introduced?
  • How is match-case different from a chain of if/elif?
  • What is structural pattern matching?
  • How do you match multiple values in a single case?
  • What is a guard condition in a case clause?
  • How does the wildcard _ pattern work?
  • Can match destructure sequences and dictionaries?

FAQ

Is match-case the same as a switch statement? +

It is more powerful. A C-style switch only compares one value. Python’s match does structural pattern matching: it can unpack sequences, dicts, and objects, bind variables, and apply guard conditions.

Which Python version do I need for match? +

Python 3.10 or newer. On older versions the keyword does not exist and you must use if/elif/else instead.

What does the underscore _ do in a case? +

It is the wildcard pattern: it matches anything and binds nothing, so it works as the catch-all default branch, usually placed last.

When should I prefer match over if/elif? +

Use match when you are dispatching on the shape or structure of data — unpacking tuples, dicts, or classes. For a couple of simple equality or range checks, a plain if/elif chain is clearer.