Pattern Matching

Beginner · 16 min read · ▶ live playground · ✦ checkpoint

Sometimes an if/elif chain starts to feel like checking the same ticket over and over. Python has a cleaner tool for that shape of problem: pattern matching, which compares one value against several patterns, exact values or shapes Python can recognize, and runs the first case that fits.

The match statement

A match statement is Python's way to compare one value against a set of possible patterns. The value after match is the subject, the value being checked. A case is one possible pattern inside the match statement, and Python tries the cases from top to bottom.

Think of a mail sorter with labeled slots. The subject comes in, Python checks the first slot, then the next, and the first slot that fits gets the letter.

mood = "hungry"
 
match mood:
    case "hungry":
        print("Preparing soup")
    case "tired":
        print("Dim the lights")
    case "curious":
        print("Open the puzzle box")
    case _:
        print("Ask again")

Preparing soup

The line case _: is the fallback. The underscore _ is a wildcard, a pattern that matches anything. Put it last, because once _ matches, no later case can run.

Order matters here, just like if/elif. The first matching case wins, then the whole match statement is done.

Matching literal values

A literal pattern is a pattern that matches one exact value written directly in the code, such as "hungry", 404, True, or None. Literal patterns are best when a value has a few clear names or codes.

status = "late"
 
match status:
    case "paid":
        message = "Ticket confirmed"
    case "late":
        message = "Send a reminder"
    case "cancelled":
        message = "Release the seat"
    case _:
        message = "Ask a human"
 
print(message)

Send a reminder

This reads like a menu: paid, late, cancelled, or anything else. You could write the same logic with if/elif, but match keeps the repeated question out of the way. The subject is status, so each case can focus on one possible value.

Matching sequences

A sequence is an ordered group of items; a list is one kind of sequence. A collection is a value that holds multiple values, and Section 5 teaches lists and other collections properly. For now, read ["move", "north"] as two pieces in order: the command word, then the direction.

Sequence patterns let Python check both the length and the items.

command = ["move", "north"]
 
match command:
    case ["move", direction]:
        print(f"Moving {direction}")
    case ["say", words]:
        print(f"You say: {words}")
    case ["quit"]:
        print("Saving game")
    case _:
        print("Unknown command")

Moving north

The pattern ["move", direction] means: match a two-item sequence whose first item is exactly "move", then store the second item in the name direction.

A capture is a bare name in a pattern that receives part of the matched value. Quoted text compares; bare names capture. That one rule saves a lot of confusion.

Try it — route a tiny command

Change the command line. Try ["look"], ["use", "key"], and ["dance"]. Keep the square brackets for now; you'll understand them fully in Section 5.

python — playgroundlive
⌘/Ctrl + Enter to run

Matching structures

A dictionary is a value that stores labeled pieces under keys, labels used to find those pieces; Section 6 teaches dictionaries properly. A structure pattern is a pattern that checks for named pieces inside a dictionary-shaped value.

ticket = {"kind": "student", "paid": True}
 
match ticket:
    case {"kind": "student", "paid": True}:
        print("Student ticket confirmed")
    case {"kind": "guest"}:
        print("Guest ticket")
    case {"kind": kind}:
        print(f"Other ticket: {kind}")
    case _:
        print("Invalid ticket")

Student ticket confirmed

Read the first case as: does this dictionary have a kind key with the value "student" and a paid key with the value True? If yes, run that block.

Dictionary patterns check for the pieces you name. Extra pieces do not block a match. That makes them useful when incoming data has a shape you care about, plus details you do not need yet.

When match beats if

Reach for match when one subject can take several clear shapes:

  • A command is "start", "help", or "quit".
  • A command sequence starts with "take" or "use".
  • A dictionary-shaped ticket has a "kind" and maybe other named pieces.

Reach for if/elif when the logic is really a set of tests:

  • score >= 90
  • age >= 18 and has_ticket
  • if nickname:
  • calculations, ranges, and truthiness checks
age = 17
has_ticket = True
with_adult = False
 
if age >= 18 and has_ticket:
    print("Adult entry")
elif has_ticket and with_adult:
    print("Entry with adult")
else:
    print("No entry today")

No entry today

That example belongs to if because the branches depend on comparisons and logical operators. Pattern matching is not a better if; it is a better tool when the shape of one value is the story.

Checkpoint

Answer all three to mark this lesson complete

You now have two ways to choose a path: if for tests, and match for clear shapes. Next, your programs stop choosing just once and start repeating useful work with loops.

+50 XP on completion