PEP 622 Pattern Matching
TL;DR
PEP 622 introduced match-case
statements for structural pattern matching, enabling elegant destructuring and dispatch based on data shape and values.
Interesting!
Pattern matching brings functional programming elegance to Python - you can destructure complex nested data in a single line and handle different cases cleanly!
Basic Match Statement
python code snippet start
def handle_data(data):
match data:
case 0:
return "zero"
case 1 | 2 | 3:
return "small number"
case int(x) if x > 100:
return f"large number: {x}"
case str(s) if len(s) < 5:
return f"short string: {s}"
case _:
return "something else"
print(handle_data(0)) # zero
print(handle_data(150)) # large number: 150
print(handle_data("hi")) # short string: hi
python code snippet end
Sequence Patterns
python code snippet start
def analyze_list(items):
match items:
case []:
return "empty list"
case [x]:
return f"single item: {x}"
case [x, y]:
return f"pair: {x}, {y}"
case [x, *rest]:
return f"starts with {x}, has {len(rest)} more"
case _:
return "not a list"
print(analyze_list([])) # empty list
print(analyze_list([1, 2, 3, 4])) # starts with 1, has 3 more
python code snippet end
Mapping Patterns
python code snippet start
def process_request(request):
match request:
case {"action": "get", "resource": resource}:
return f"Getting {resource}"
case {"action": "post", "resource": resource, "data": data}:
return f"Posting to {resource}: {data}"
case {"action": "delete", "resource": resource, "confirm": True}:
return f"Deleting {resource}"
case {"action": "delete", "resource": resource}:
return f"Delete {resource} requires confirmation"
case _:
return "Invalid request"
request1 = {"action": "get", "resource": "users"}
print(process_request(request1)) # Getting users
python code snippet end
Class Patterns
python code snippet start
from dataclasses import dataclass
@dataclass
class Point:
x: float
y: float
@dataclass
class Circle:
center: Point
radius: float
def describe_shape(shape):
match shape:
case Point(0, 0):
return "origin point"
case Point(x, 0):
return f"point on x-axis at {x}"
case Point(0, y):
return f"point on y-axis at {y}"
case Point(x, y):
return f"point at ({x}, {y})"
case Circle(Point(0, 0), radius):
return f"circle at origin with radius {radius}"
case Circle(center, radius):
return f"circle at {center} with radius {radius}"
case _:
return "unknown shape"
shapes = [
Point(0, 0),
Point(3, 0),
Circle(Point(1, 2), 5)
]
for shape in shapes:
print(describe_shape(shape))
python code snippet end
Complex Nested Patterns
python code snippet start
def parse_expression(expr):
match expr:
case {"type": "number", "value": n}:
return n
case {"type": "add", "left": left, "right": right}:
return parse_expression(left) + parse_expression(right)
case {"type": "multiply", "left": left, "right": right}:
return parse_expression(left) * parse_expression(right)
case {"type": "variable", "name": name}:
return f"var_{name}"
case _:
return "invalid expression"
# Parse: (2 + 3) * 4
expr = {
"type": "multiply",
"left": {
"type": "add",
"left": {"type": "number", "value": 2},
"right": {"type": "number", "value": 3}
},
"right": {"type": "number", "value": 4}
}
print(parse_expression(expr)) # 20
python code snippet end
Guards and Conditions
python code snippet start
def categorize_triangle(sides):
match sides:
case [a, b, c] if a == b == c:
return "equilateral"
case [a, b, c] if a == b or b == c or a == c:
return "isosceles"
case [a, b, c] if a + b > c and b + c > a and a + c > b:
return "scalene"
case [a, b, c] if a**2 + b**2 == c**2:
return "right triangle"
case _:
return "not a valid triangle"
print(categorize_triangle([3, 3, 3])) # equilateral
print(categorize_triangle([3, 4, 5])) # right triangle
python code snippet end
Pattern matching transforms complex conditional logic into readable, expressive code - especially powerful for parsing, data processing, and type-based dispatch!
Pattern matching works beautifully with control flow structures and Python's data structures for elegant code organization.
Reference: PEP 622 – Structural Pattern Matching