PyCon Redux
GitHub Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage
Edit page

Match Statement

This talk on structural pattern matching (the match statement) was given by PEP 634’s coauthor Brandt Bucher.

Notable sayings from the talk:

  • Structural pattern matching is not a switch statement!
  • Want practice? Implement a red-black tree with structural pattern matching

Structural pattern matching is 80% faster than similarly structured conditional structures, thanks to custom bytecode instructions like MATCH_STATEMENT.

To see how the match statement looks in a basic conditional structure:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
from dataclasses import dataclass
from datetime import datetime
from enum import Enum


class Status(str, Enum):
    DELIVERED = "delivered"
    PLANNED = "planned"
    OTHER = "other"


@dataclass
class Talk:
    status: Status
    date: datetime


today = datetime.today()


def get_display_brute_conditionals(talk: Talk) -> str | None:
    if talk.status == Status.PLANNED:
        if talk.date > today:
            return "future"
        return "cancelled"
    if talk.status == Status.DELIVERED:
        if talk.date > today:
            return "rescheduled"
        return "past"
    return None


def get_display_condensed_conditionals(talk: Talk) -> str | None:
    if talk.status == Status.PLANNED:
        return "future" if talk.date > today else "cancelled"
    if talk.status == Status.DELIVERED:
        return "rescheduled" if talk.date > today else "past"
    return None


def get_display_lookup(talk: Talk) -> str | None:
    displays = {
        (Status.PLANNED, True): "future",
        (Status.PLANNED, False): "cancelled",
        (Status.DELIVERED, True): "rescheduled",
        (Status.DELIVERED, False): "past",
    }
    return displays.get((talk.status, talk.date > today), None)


def get_display_match(talk: Talk) -> str | None:
    match talk.status, talk.date > today:
        case Status.PLANNED, True:
            return "future"
        case Status.PLANNED, False:
            return "cancelled"
        case Status.DELIVERED, True:
            return "rescheduled"
        case Status.DELIVERED, False:
            return "past"
        case _:
            return None