How to use match-case in Python (hint: not for if statements)

Published: (February 12, 2026 at 11:29 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

match-case is Python’s structural pattern‑matching feature (introduced in Python 3.10).
Think of it as a much more powerful switch, designed to match not just values but also shapes and structures of data.

Many people think that match-case is a fancy way of doing if statements. You can, but its purpose goes beyond that.

1. Basic idea (value matching)

At its simplest, it looks like a switch statement in other languages:

def http_status_message(status):
    match status:
        case 200:
            return "OK"
        case 404:
            return "Not Found"
        case 500:
            return "Server Error"
        case _:
            return "Unknown status"

Key points

  • match evaluates once.
  • Cases are tried top‑to‑bottom.
  • _ is the wildcard (default case).

Equivalent if version:

def http_status_message(status):
    if status == 200:
        return "OK"
    elif status == 404:
        return "Not Found"
    elif status == 500:
        return "Server Error"
    else:
        return "Unknown status"

For simple look‑ups a dictionary may be clearer:

def http_status_message(status):
    messages = {
        200: "OK",
        404: "Not Found",
        500: "Server Error",
    }
    return messages.get(status, "Unknown status")

2. Structural pattern‑matching (shapes and structures of data)

Tuple / sequence matching

point = (0, 5)

match point:
    case (0, y):
        print(f"On Y axis at y={y}")
    case (x, 0):
        print(f"On X axis at x={x}")
    case (x, y):
        print(f"At ({x}, {y})")
  • (0, y) means the first element must be 0; the second element is captured as y.
  • This matches the shape of the object, not just equality.

3. Matching lists with rest (*)

numbers = [1, 2, 3, 4]

match numbers:
    case [first, *rest]:
        print(first, rest)
  • *rest captures the remaining elements.
  • It can appear only once per pattern.

4. Type and class matching

Simple type matching

def handle(value):
    match value:
        case int():
            print("Integer")
        case str():
            print("String")
        case list():
            print("List")

Class pattern matching

class User:
    def __init__(self, name, is_admin):
        self.name = name
        self.is_admin = is_admin

user = User("Alice", True)

match user:
    case User(name=name, is_admin=True):
        print(f"Admin: {name}")
    case User(name=name):
        print(f"User: {name}")
  • Checks that the object is an instance of User and then matches its attributes.

5. Guards (if inside case)

Sometimes you need an additional condition:

match value:
    case int(x) if x > 0:
        print("Positive integer")
    case int(x):
        print("Non‑positive integer")

6. OR patterns (|)

match command:
    case "start" | "run" | "go":
        print("Starting…")
    case "stop" | "quit":
        print("Stopping…")

7. Dict (mapping) matching

data = {"type": "error", "code": 404}

match data:
    case {"type": "error", "code": code}:
        print(f"Error code {code}")
  • Extra keys are allowed by default; only the listed keys must match.

Takeaway

  • match-case asks: “Does this value have this shape?
  • if asks: “Is this condition true?

Extra reading

0 views
Back to Blog

Related posts

Read more »

Cast Your Bread Upon the Waters

!Cover image for Cast Your Bread Upon the Watershttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-t...