When you need to pick one of many actions based on a single value, an
if/elif chain works but gets noisy fast. Python 3.10 added the match statement: it reads like a switch table and is easier to scan.Literal patterns
command = 'quit'
match command:
case 'go':
print('moving')
case 'look':
print('describing room')
case 'quit' | 'exit': # '|' means "or"
print('bye')
case _:
print('unknown command')case lines test the value that follows match. The first line that matches runs, and execution stops there — no fall-through. _ is a wildcard that catches anything not matched earlier.Capturing values with sequence patterns
# 'go north' -> ['go', 'north']
words = ['drop', 'sword', 'shield']
match words:
case []: # empty list
print('nothing typed')
case ['drop', *items]: # 'drop' plus any number of items
print('dropping:', items)
case [verb]: # exactly one word, captured as verb
print(f'verb is {verb}')
case [verb, direction]: # exactly two words
print(f'{verb} toward {direction}')* is a star pattern: it grabs zero or more remaining elements into a list. Patterns run top to bottom, so the specific 'drop' case comes before the general two-word case: otherwise drop sword would be caught as a verb and a direction.Mapping patterns and guards
event = {'type': 'move', 'x': 3, 'y': -1}
match event:
case {'type': 'move', 'x': x, 'y': y} if x > 0: # a shape plus a guard
print(f'move right to ({x}, {y})')
case {'type': 'move', 'x': x, 'y': y}:
print(f'move to ({x}, {y})')
case {'type': t}: # any other dict with a 'type' key
print('got type:', t)
case _:
print('not an event')if after a pattern is a guard: the case only matches when both the shape and the condition are true. This keeps your patterns declarative without nesting ifs inside each branch.A mapping pattern matches any dictionary that has at least those keys: extra keys are fine. That is why the general
{'type': t} case has to come last.