Ratul was here

πŸš€ 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:

  1. 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
      
  2. Match Multiple Patterns

    • Handle different command lengths gracefully:
      match command.split():
          case [action]:
              ... # interpret single-verb action
          case [action, obj]:
              ... # interpret action, obj
      
  3. 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)
      
  4. Match Multiple Values

    • Allow complex commands with variable lengths:
      match command.split():
          case ["drop", *objects]:
              for obj in objects:
                  character.drop(obj, current_room)
      
  5. Add a Wildcard

    • Catch-all for unrecognized commands:
      match command.split():
          case _:
              print(f"Sorry, I couldn't understand {command!r}")
      
  6. 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")
      
  7. 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
      
  8. 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)
      
  9. 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")
      
  10. 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}")
      
  11. 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)
      
  12. 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
      
  13. 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")
      

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.


#advanced #python