Python Tutorial menu

Python match Statement

The match statement compares a value against patterns and runs the first case that fits.

A Quick Reminder

The If...Else lesson showed a simple match. It needs Python 3.10 or newer. The shape is:

Example

python
match value:
    case pattern1:
        ...
    case pattern2:
        ...
    case _:
        ...

Python checks the cases from top to bottom. Only the first matching case runs. case _ is the "anything else" case.

match can do much more than compare numbers. It can look inside lists, dictionaries and objects. This is called structural pattern matching.

Several Values in One Case

Use | (read it as "or") to join values.

Example

python
def day_type(day):
    match day.lower():
        case "saturday" | "sunday":
            return "Weekend"
        case "friday":
            return "Half day"
        case "monday" | "tuesday" | "wednesday" | "thursday":
            return "Working day"
        case _:
            return "Not a day"

for d in ["Sunday", "Friday", "Tuesday", "Funday"]:
    print(d, "->", day_type(d))
Output
Sunday -> Weekend
Friday -> Half day
Tuesday -> Working day
Funday -> Not a day

Guards: Adding a Condition

Add if after a pattern to check an extra condition. This is called a guard. A plain name in a pattern (like m below) catches the value so you can use it.

Example

python
def grade(m):
    match m:
        case m if m < 0 or m > 100:
            return "Invalid"
        case m if m >= 80:
            return "A"
        case m if m >= 60:
            return "B"
        case _:
            return "C"

print(grade(91), grade(67), grade(40), grade(150))
Output
A B C Invalid

Matching Lists and Tuples

A pattern can describe the shape of a sequence. Names inside the pattern grab the matching items.

Example

python
def run(command):
    match command.split():
        case ["help"]:
            print("Commands: add, remove, list")
        case ["add", item]:
            print(f"Adding {item}")
        case ["add", item, qty]:
            print(f"Adding {qty} x {item}")
        case ["remove", *items]:
            print("Removing", ", ".join(items))
        case []:
            print("Type something")
        case _:
            print("Unknown command")

run("help")
run("add milk")
run("add eggs 12")
run("remove bread butter jam")
run("")
run("dance")
Output
Commands: add, remove, list
Adding milk
Adding 12 x eggs
Removing bread, butter, jam
Type something
Unknown command

*items collects the rest of the list, just like *args in a function. Writing this with if/elif would need many length checks and index lookups.

Matching Dictionaries

A dictionary pattern checks that certain keys exist and grabs their values. Extra keys are allowed.

Example

python
def handle(event):
    match event:
        case {"type": "order", "item": item, "qty": qty}:
            print(f"New order: {qty} x {item}")
        case {"type": "payment", "amount": int(amount)} if amount > 0:
            print(f"Payment received: Rs {amount}")
        case {"type": t}:
            print(f"Ignoring event type '{t}'")

handle({"type": "order", "item": "biryani", "qty": 2, "table": 5})
handle({"type": "payment", "amount": 1800})
handle({"type": "payment", "amount": "free"})
handle({"type": "login"})
Output
New order: 2 x biryani
Payment received: Rs 1800
Ignoring event type 'payment'
Ignoring event type 'login'

int(amount) matches only when the value is an int. The text "free" is not, so that event falls to the last case. This is very handy for data that comes from JSON or an API.

Matching Objects

You can also match the type and attributes of an object. Dataclasses work very well with match.

Example

python
from dataclasses import dataclass

@dataclass
class Point:
    x: int
    y: int

def where(p):
    match p:
        case Point(x=0, y=0):
            return "At the origin"
        case Point(x=0, y=y):
            return f"On the y-axis at {y}"
        case Point(x=x, y=0):
            return f"On the x-axis at {x}"
        case Point():
            return "Somewhere else"
        case _:
            return "Not a point"

print(where(Point(0, 0)))
print(where(Point(0, 7)))
print(where(Point(3, 0)))
print(where(Point(2, 5)))
print(where("hello"))
Output
At the origin
On the y-axis at 7
On the x-axis at 3
Somewhere else
Not a point

Pattern Cheat Sheet

PatternMatches
case 5: or case "yes":That exact value
Values joined by the bar symbol, as in the weekend exampleAny one of those values
case x:Anything, and stores it in x
case _:Anything (stores nothing)
case [a, b]:A sequence of exactly two items
case [first, *rest]:A sequence with at least one item
case {"key": v}:A dict that has that key
case int(n):An int, stored in n
case Point(x=0):A Point object whose x is 0
case p if p > 0:Any value that also passes the guard

A bare name like case total: does not compare with a variable called total. It always matches and overwrites the name. To compare with a stored constant, use a dotted name such as case Colour.RED:.

Exercise

Exercise

Which case matches the list ["add", "tea", "3"]?

Learn Python with a teacher

Join the Python Programming course at Workownix, online or in Orangi Town, Karachi, and get a certificate.

See the course Ask on WhatsApp