π Unlocking the Power of Structural Pattern Matching in Python π
Are you aware of the new pattern matching feature first introduced in Python 3.10? Hereβs a comprehensive guide to help you understand and master it!
Pattern matching, introduced in PEP 634, is a game-changer. It's a powerful feature that allows you to match data structures against patterns and extract information from them seamlessly.
Here's a quick overview:
Match Sequences
- Simplify your text-based adventure game commands:
command = input("What are you doing next? ") match command.split(): case [action, obj]: ... # interpret action, obj
- Simplify your text-based adventure game commands:
Match Multiple Patterns
- Handle different command lengths gracefully:
match command.split(): case [action]: ... # interpret single-verb action case [action, obj]: ... # interpret action, obj
- Handle different command lengths gracefully:
Match Specific Values
- Execute logic based on specific commands:
match command.split(): case ["quit"]: print("Goodbye!") quit_game() case ["look"]: current_room.describe() case ["get", obj]: character.get(obj, current_room) case ["go", direction]: current_room = current_room.neighbor(direction)
- Execute logic based on specific commands:
Match Multiple Values
- Allow complex commands with variable lengths:
match command.split(): case ["drop", *objects]: for obj in objects: character.drop(obj, current_room)
- Allow complex commands with variable lengths:
Add a Wildcard
- Catch-all for unrecognized commands:
match command.split(): case _: print(f"Sorry, I couldn't understand {command!r}")
- Catch-all for unrecognized commands:
Composing Patterns
- Nest patterns within each other for complex matches:
match points: case []: print("No points") case [Point(0, 0)]: print("The origin") case [Point(x, y)]: print(f"Single point {x}, {y}") case [Point(0, y1), Point(0, y2)]: print(f"Two on the Y axis at {y1}, {y2}") case _: print("Something else")
- Nest patterns within each other for complex matches:
Or Patterns
- Combine multiple patterns with the same outcome:
match command.split(): case ["north"] | ["go", "north"]: current_room = current_room.neighbor("north") case ["get", obj] | ["pick", "up", obj] | ["pick", obj, "up"]: ... # Code for picking up the given object
- Combine multiple patterns with the same outcome:
Capturing Matched Sub-patterns
- Capture values from sub-patterns:
match command.split(): case ["go", ("north" | "south" | "east" | "west") as direction]: current_room = current_room.neighbor(direction)
- Capture values from sub-patterns:
Adding Conditions to Patterns
- Use guards to add conditions to your matches:
match command.split(): case ["go", direction] if direction in current_room.exits: current_room = current_room.neighbor(direction) case ["go", _]: print("Sorry, you can't go that way")
- Use guards to add conditions to your matches:
Matching Objects
- Match objects and their attributes:
match event.get(): case Click(position=(x, y)): handle_click_at(x, y) case KeyPress(key_name="Q") | Quit(): game.quit() case KeyPress(key_name="up arrow"): game.go_north() case KeyPress(): pass # Ignore other keystrokes case other_event: raise ValueError(f"Unrecognized event: {other_event}")
- Match objects and their attributes:
Matching Positional Attributes
- Use positional attributes in patterns:
from dataclasses import dataclass @dataclass class Click: position: tuple button: Button match event.get(): case Click((x, y)): handle_click_at(x, y)
- Use positional attributes in patterns:
Matching Against Constants and Enums
- Match against constants and enums:
match event.get(): case Click((x, y), button=Button.LEFT): # This is a left click handle_click_at(x, y) case Click(): pass # ignore other clicks
- Match against constants and enums:
Matching Mappings
- Match against dictionary keys and values:
for action in actions: match action: case {"text": str(message), "color": str(c)}: ui.set_text_color(c) ui.display(message) case {"sleep": float(duration)}: ui.wait(duration) case {"sound": str(url), "format": "ogg"}: ui.play(url) case {"sound": _, "format": _}: warning("Unsupported audio format")
- Match against dictionary keys and values:
Pattern matching is not just about matching sequences or values; itβs about unlocking a new level of expressiveness in your code.
Let's make python more intuitive and powerful with pattern matching! π Also go see the official tutorial as pep here PEP 0636.
If you found this helpful, consider resharing β»οΈ and follow me for more content like this.