indusai.co

Match statements

The match statement, added in Python 3.10, compares a value against several patterns and runs the block for the first pattern that fits. It replaces long chains of if x == ...: elif x == ...: and can also pull values out of structured data.

Matching simple values

python
def http_status(code):
    match code:
        case 200:
            return "OK"
        case 404:
            return "Not found"
        case 500 | 502 | 503:
            return "Server error"
        case _:
            return "Unknown"

print(http_status(200), http_status(503), http_status(418))
  • Each case is tested in order.
  • | means "or".
  • case _: is the wildcard that matches anything, like else.

Matching strings

python
command = "stop"
match command:
    case "start":
        print("Starting")
    case "stop":
        print("Stopping")
    case _:
        print("Unknown command")

Capturing values

A bare name in a pattern captures whatever is there.

python
def describe(point):
    match point:
        case (0, 0):
            return "origin"
        case (x, 0):
            return f"on the x axis at {x}"
        case (0, y):
            return f"on the y axis at {y}"
        case (x, y):
            return f"at ({x}, {y})"

print(describe((0, 0)))
print(describe((5, 0)))
print(describe((3, 4)))

Matching lists

python
def summarise(items):
    match items:
        case []:
            return "empty"
        case [only]:
            return f"one item: {only}"
        case [first, *rest]:
            return f"starts with {first}, then {len(rest)} more"

print(summarise([]))
print(summarise(["a"]))
print(summarise([1, 2, 3, 4]))

Matching dictionaries

Only the listed keys need to be present; extra keys are ignored.

python
event = {"type": "click", "x": 10, "y": 20}
match event:
    case {"type": "click", "x": x, "y": y}:
        print(f"Clicked at {x}, {y}")
    case {"type": "key", "key": k}:
        print(f"Pressed {k}")

Guards

Add if to a case for an extra condition.

python
def bucket(n):
    match n:
        case int() if n < 0:
            return "negative"
        case int() if n == 0:
            return "zero"
        case int():
            return "positive"
        case _:
            return "not an integer"

print(bucket(-3), bucket(0), bucket(9), bucket("x"))

int() in a pattern checks the type without calling anything.

When to use match

Reach for match when you are branching on the shape of data: tuples, lists, dictionaries, or objects with attributes. For a single comparison a plain if is still clearer.

Practice

  1. Write a match that converts the strings "mon", "tue" and "wed" to full day names and returns "invalid" otherwise.
  2. Write a function that accepts a tuple describing a shape, such as ("circle", 5) or ("rect", 3, 4), and returns its area using match.