
Pattern Matching with Functions in Python
Python's pattern matching is a game-changer, allowing for elegant and efficient comparisons of variables against multiple patterns. The result? Execute specific code blocks depending on which pattern aligns first.
This revolves around the match statement paired with case clauses.
- match variable:
- case pattern1:
- # Implement an action
- case pattern2:
- # Execute a different course of action
- case _:
- # The underscore (_) acts as a universal match
Introduced in Python 3.10, this feature has significantly enhanced code readability and maintainability, particularly when handling intricate data.
For programmers versed in other languages, Python's pattern matching might initially seem unconventional. However, it's a robust feature that enriches the functional programming experience in Python.
Let's delve into some real-world examples.
Consider a function that links simple input values to corresponding output strings.
- def describe_number(number):
- match number:
- case 1:
- return "One"
- case 2:
- return "Two"
- case _:
- return "Other number"
When calling this function with 1, it executes the corresponding case, returning "One" as the output.
print(describe_number(1))
One
If you invoke the function with 3, it defaults to the catch-all case, returning "Other number."
The underscore "_" serves as a wildcard, capturing any unmatched cases.
print(describe_number(3))
Other number
Pattern Matching with Lists and Tuples
Pattern matching shines when applied to complex data structures like lists and tuples.
Take this script, for instance, which analyzes a list input:
- def analyze_list(list):
- match list:
- case []:
- return "Empty list"
- case [first_element]:
- return f"List with one element: {first_element}"
- case [first, *rest]:
- return f"List with multiple elements, the first being: {first}"
For a multi-element list, the script smartly identifies and responds to the specific structure .
print(analyze_list([1, 2, 3]))
List with multiple elements, the first being: 1
Here's another example, further illustrating the flexibility of pattern matching:
- def analyze_data(data):
- match data:
- case (a, b, c):
- print(f"Three elements: {a}, {b}, {c}")
- case [a, b, *rest]:
- print(f"List with at least two elements: {a}, {b}, other elements: {rest}")
- case _:
- print("Pattern not recognized")
Passing a three-element tuple triggers the corresponding case, revealing the flexibility of this approach.
analyze_data((1, 2, 3))
Three elements: 1, 2, 3
A five-element list prompts a different case, demonstrating adaptability to various data structures.
analyze_data([1, 2, 3, 4, 5])
List with at least two elements: 1, 2, other elements: [3, 4, 5]
Pattern Matching with Objects
Extending pattern matching to objects opens up a realm of possibilities.
- class Car:
- def __init__(self, make, model):
- self.make = make
- self.model = model
- def describe_car(car):
- match car:
- case Car(make="Fiat", model=model):
- return f"Fiat car, model {model}"
- case Car(make=make, model=_):
- return f"Car of make {make}"
- case _:
- return "Unidentified object"
- car = Car("Fiat", "500")
- print(describe_car(car))
By passing an object to the function, it intuitively discerns the relevant details and provides a concise output.
Fiat car, model 500
Through pattern matching, Python scripts become not only more readable but also elegantly structured and versatile.