Match Statements¶

Introduced in Python 3.10, these are flexible versions of a switch statement. A match expression is evaluated and compared in turn to various patterns. Each pattern can have a guard expression and capture variables.

A match statement can be used like a switch statement in C. There is no break required between cases.

In [2]:
for x in range(4):
    match x:
        case 1 | 2:
            print('1 or 2')
        case 3:
            print('3')
1 or 2
1 or 2
3

But the match statement is more powerful:

  • We can match aggregate objects and "capture" [parts of] the match expression to variables.
  • We can add a "guard expression" for more complex matches.
  • A single variable (or _) as the last case will match anything.
  • Variables used to capture parts of the matched expressions retain their values after the block.
In [4]:
for x in [("zebra",100.00),("Giraffe",250.00),("Worm",1.00),(1,2,3)]:
    match x:
        case ("Zebra"|"zebra"),v:
            print(f'Zebras cost ${v:.2f}')            
        case s,v if v > 50:
            print(f'A {s} is expensive, it costs ${v}')
        case s,v:
            print(f'A {s} is not a zebra or expensive, it costs ${v}')
        case u:
            print(f"{u}: this doesn't match anything I was expecting")
            
print(f"\ns={s} v={v} u={u}")
Zebras cost $100.00
A Giraffe is expensive, it costs $250.0
A Worm is not a zebra or expensive, it costs $1.0
(1, 2, 3): this doesn't match anything I was expecting

s=Worm v=1.0 u=(1, 2, 3)

Patterns can also include constructors for a built-in type such as str, or for user-defined types. An as clause in the pattern can specify a capture variable. For example:

In [3]:
class AnimalCost(float):
    pass

for x in [("zebra",100.00),("Giraffe",250.00),("Worm",1.00),(1,2,3)]:
    match x:
        case str as animal, AnimalCost as cost:
            print(f"A {animal} costs {cost}")
        case u:
            print(f"{u}: unexpected")
            
A zebra costs 100.0
A Giraffe costs 250.0
A Worm costs 1.0
(1, 2, 3): unexpected