GeezerVisonThe World Wide Web, restored to 800 pixels of glory. |
| Home|About|Gaming cabinet|Archives|How it works|Starter sites |
GeezerVison is showing zetcode.com — Python pattern match - pattern matching in Python with match/case Python pattern matchlast modified January 29, 2024 In this article we show how to use pattern matching in Python.
Pattern matching is done with Pattern matching is a powerful control flow construct that allows us to compare a value against a series of patterns and then execute code based on which pattern matches. It is a much more advanced construct than the if/else statements or the classic switch statements. In if/else or switch statements, each individual condition is called a branch; in pattern matching, the term arm is used instead. Python pattern match literalsIn the first example, we match against simple literal values. hello.py
#!/usr/bin/python
langs = ['russian', 'slovak', 'german',
'swedish', 'hungarian', 'french', 'spanish']
print('say hello')
for lang in langs:
match lang:
case 'russian':
print('привет')
case 'hungarian':
print('szia')
case 'french':
print('salut')
case 'spanish':
print('hola')
case 'slovak':
print('ahoj')
case 'german':
print('hallo')
case 'swedish':
print('Hallå')
We have a list of languages. We go through the list and say hello for each language. for lang in langs:
match lang:
The case 'russian':
print('привет')
Each arm is started with a $ ./first.py say hello привет ahoj hallo Hallå szia salut hola Python pattern match multiple options
We can have multiple options for a single line with grades.py
#!/usr/bin/python
grades = ['A', 'B', 'C', 'D', 'E', 'F', 'FX']
for grade in grades:
match grade:
case 'A' | 'B' | 'C' | 'D' | 'E' | 'F':
print('passed')
case 'FX':
print('failed')
We have a list of grades. For A through F grades, we pass the example. For the FX grade, we fail the exam. $ ./grades.py passed passed passed passed passed passed failed Python pattern match wildcard
We can use the wildcard character factorial.py
#!/usr/bin/python
def factorial(n):
match n:
case 0 | 1:
return 1
case _:
return n * factorial(n - 1)
for i in range(17):
print(i, factorial(i))
We create a factorial function with match n:
case 0 | 1:
return 1
case _:
return n * factorial(n - 1)
For values 0 and 1, we return 1. For all other values, we recursively call the factorial function. $ ./factorial.py 0 1 1 1 2 2 3 6 4 24 5 120 6 720 7 5040 8 40320 9 362880 10 3628800 11 39916800 12 479001600 13 6227020800 14 87178291200 15 1307674368000 16 20922789888000 Python pattern match guardsGuards in the form of if conditions can be executed on an arm. guards.py
#!/usr/bin/python
import random
n = random.randint(-5, 5)
match n:
case n if n < 0:
print(f"{n}: negative value")
case n if n == 0:
print(f"{n}: zero")
case n if n > 0:
print(f"{n}: positive value")
The example chooses a random integer. With case n if n < 0:
print(f"{n}: negative value")
This arm is executed if the n is less than zero. Python matter match objectsWe can use pattern matching on Python objects. objects.py
from dataclasses import dataclass
@dataclass
class Cat:
name: str
@dataclass
class Dog:
name: str
@dataclass
class Person:
name: str
data = [Cat('Missy'), Dog('Jasper'), Dog('Ace'), Person('Peter'), 'Jupiter']
for e in data:
match e:
case Cat(name) | Dog(name):
print(f'{name} is a pet')
case Person(name):
print(f'{name} is a human')
case _:
print(f'unknown')
We have three classes: case Cat(name) | Dog(name):
print(f'{name} is a pet')
This arm checks either for a cat or for a dog. case Person(name):
print(f'{name} is a human')
This arm checks for a person object. case _:
print(f'unknown')
For an object that we cannot identify, we use the wildcard. $ ./objects.py Missy is a pet Jasper is a pet Ace is a pet Peter is a human unknown
In the next example, we work with points.py
#!/usr/bin/python
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
def check(p):
match p:
case Point(x=0, y=0):
print("Origin")
case Point(x, y) if y == 0:
print(f"on x axis")
case Point(x, y) if x == 0:
print(f"on y axis")
case Point(x, y) if x > 0 and y > 0:
print("Q I")
case Point(x, y) if x < 0 and y > 0:
print("Q II")
case Point(x, y) if x < 0 and y < 0:
print("Q III")
case Point(x, y) if x > 0 and y < 0:
print("Q IV")
case _:
print("Not a point")
points = [Point(3, 0), Point(0, 0), Point(-4, -5), Point(-4, 0), Point(0, 5),
Point(4, 8), Point(-5, 3), Point(6, -4)]
for p in points:
check(p)
Depending on the coordinates, we assign the point objects to the origin, x and y axis, or one of the four quadrants. $ ./points.py on x axis Origin Q III on x axis on y axis Q I Q II Q IV Python pattern match enumsPattern matching can be effectively used with enums. enum.py
#!/usr/bin/python
from enum import Enum
import random
Day = Enum('Day', 'Monday Tuesday Wednesday Thursday Friday Saturday Sunday')
days = [Day.Monday, Day.Tuesday, Day.Wednesday,
Day.Thursday, Day.Friday, Day.Saturday, Day.Sunday]
res = random.sample(days, 4)
for e in res:
match e:
case Day.Monday:
print("monday")
case Day.Tuesday:
print("tuesday")
case Day.Wednesday:
print("wednesay")
case Day.Thursday:
print("thursday")
case Day.Friday:
print("friday")
case Day.Saturday:
print("saturday")
case Day.Sunday:
print("sunday")
In the example, we define a days = [Day.Monday, Day.Tuesday, Day.Wednesday,
Day.Thursday, Day.Friday, Day.Saturday, Day.Sunday]
res = random.sample(days, 4)
We randomly choose four days from a list. for e in res:
match e:
case Day.Monday:
print("monday")
case Day.Tuesday:
print("tuesday")
case Day.Wednesday:
print("wednesay")
case Day.Thursday:
print("thursday")
case Day.Friday:
print("friday")
case Day.Saturday:
print("saturday")
case Day.Sunday:
print("sunday")
We check the four chosen values and print their corresponding string representations. $ ./enums.py friday monday thursday tuesday Python pattern match tuplesIn the following example, we match tuples. tuples.py
#!/usr/bin/python
users = [
('John', 'Doe', 'gardener'),
('Jane', 'Doe', 'teacher'),
('Roger', 'Roe', 'driver'),
('Martin', 'Molnar', 'programmer'),
('Robert', 'Kovac', 'shopkeeper'),
('Tomas', 'Novy', 'programmer'),
]
for user in users:
match user:
case (fname, lname, 'programmer'):
print(f'{fname} {lname} is a programmer')
case (fname, lname, 'teacher'):
print(f'{fname} {lname} is a teacher')
case (fname, lname, 'gardener'):
print(f'{fname} {lname} is a gardener')
case _:
print(user)
We have a list of tuples. Each tuple is a person and his profession. We match against the profession. case (fname, lname, 'programmer'):
print(f'{fname} {lname} is a programmer')
This arm binds the name of the person to $ ./tuples.py
John Doe is a gardener
Jane Doe is a teacher
('Roger', 'Roe', 'driver')
Martin Molnar is a programmer
('Robert', 'Kovac', 'shopkeeper')
Tomas Novy is a programmer
Python pattern match mapsIn the next example, we do pattern matching with maps. maps.py
#!/usr/bin/python
users = [
{'name': 'Paul', 'cols': ['red', 'blue', 'salmon']},
{'name': 'Martin', 'cols': ['blue']},
{'name': 'Lucia', 'cols': ['pink', 'brown']},
{'name': 'Jan', 'cols': ['blue', 'green']},
]
for user in users:
match user:
case {'name':name, 'cols': cols}:
print(f'favourite colours of {name}:')
for col in cols:
print(col)
We have a list of users represented as maps. case {'name':name, 'cols': cols}:
print(f'favourite colours of {name}:')
for col in cols:
print(col)
The $ ./maps.py favourite colours of Paul: red blue salmon favourite colours of Martin: blue favourite colours of Lucia: pink brown favourite colours of Jan: blue green SourcePEP 622 – Structural Pattern Matching In this article we have worked with Python pattern matching. AuthorMy name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming. List all Python tutorials. |
| You are visitor 01402520 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |