5. Structural Pattern Matching
Structural pattern matching lets you branch on both the kind of value you received and the structure of that value. It is often clearer than a long chain of if and elif checks when the code is dispatching on shapes of data.
5.1. Basic matching
The match statement compares one value against a sequence of case patterns.
1command = 'start'
2
3match command:
4 case 'start':
5 print('starting')
6 case 'stop':
7 print('stopping')
8 case 'pause':
9 print('pausing')
10 case _:
11 print('unknown command')
5.2. Matching structured data
Pattern matching becomes more useful when the input is structured data such as dictionaries.
1event = {'type': 'click', 'x': 10, 'y': 20}
2
3match event:
4 case {'type': 'click', 'x': x, 'y': y}:
5 print(f'click at ({x}, {y})')
6 case {'type': 'keypress', 'key': key}:
7 print(f'key pressed: {key}')
8 case _:
9 print('unknown event')
5.3. Matching with guards
Sometimes the structure matches, but you also need an extra condition. In that case, you can use a guard with if.
1point = (3, 4)
2
3match point:
4 case (x, y) if x == y:
5 print('same coordinates')
6 case (x, y) if x > y:
7 print('x is larger')
8 case (x, y):
9 print('y is larger or equal')
5.4. Why this matters
Pattern matching is useful when you are decoding commands, events, messages, or other structured inputs. It keeps the branching logic compact and makes each case read like a description of the shape you expect.
5.5. Exercise
Build a tiny chat command router using match. Support commands such as:
{'type': 'join', 'room': 'python'}{'type': 'message', 'room': 'python', 'text': 'hello'}{'type': 'leave', 'room': 'python'}
Print a different message for each command shape, and use a guard to reject empty messages.