Практическое руководство для разработчиков по использованию недавно добавленной функции Python — сопоставление структурных шаблонов с примерами.

В Python 3.10 появилась новая функция под названием Структурное сопоставление шаблонов (также известная как Выражения сопоставления), которая обеспечивает элегантный способ сопоставления шаблонов со структурами данных. Python 3.11 вносит дополнительные улучшения в эту функцию, делая ее более мощной и выразительной. В этой статье мы подробно рассмотрим эту функцию и посмотрим, как ее можно использовать, чтобы упростить наш код и сделать его более читабельным. Оставайтесь с нами!

Сопоставление структурных шаблонов

Structural Pattern Matching — это функция, которая позволяет нам сопоставлять шаблоны в структурах данных, таких как списки, кортежи и словари. Это похоже на оператор case case в других языках программирования. Это способ написать более лаконичный и выразительный код для обработки сложных структур данных.

С помощью структурного сопоставления шаблонов мы можем определить шаблон, который соответствует структуре данных, с которыми мы хотим работать. Если шаблон соответствует данным, то мы можем выполнить соответствующий код. Это делается с помощью оператора «match» в Python.

Сопоставление строк:

Вот простой пример оператора «match»:

def describe_color(color):
    match color:
        case "red":
            print("This is a red color")
        case "green":
            print("This is a green color")
        case "blue":
            print("This is a blue color")
        case _:
            print("This is an unknown color")

describe_color("red")   #This is a red color
describe_color("yellow")   #This is an unknown color

Списки соответствия:

Одной из наиболее распространенных структур данных, с которыми мы работаем, является список. Нам часто нужно сопоставлять шаблоны в списках, чтобы выполнять над ними различные операции. Со структурным сопоставлением шаблонов мы можем легко это сделать.

Вот пример сопоставления списка:

def process_list(lst):
    match lst:
        case [1, 2, 3]:
            print("Found list [1, 2, 3]")
        case [4, 5, 6]:
            print("Found list [4, 5, 6]")
        case [7, 8, 9]:
            print("Found list [7, 8, 9]")
        case _:
            print("Unknown list")


process_list([1,2,3]) #Found list [1, 2, 3]
process_list([2,3,4]) #Unknown list

Соответствие кортежей:

Кортежи — еще одна распространенная структура данных, с которой мы работаем. С помощью структурного сопоставления шаблонов мы можем сопоставлять шаблоны в кортежах так же, как мы делаем со списками.

Вот пример сопоставления кортежа:

def process_tuple(tpl):
    match tpl:
        case (1, 2, 3):
            print("Found tuple (1, 2, 3)")
        case (4, 5, 6):
            print("Found tuple (4, 5, 6)")
        case (7, 8, 9):
            print("Found tuple (7, 8, 9)")
        case _:
            print("Unknown tuple")

process_tuple((1, 2, 3)) #Found tuple (1, 2, 3)
process_tuple((2, 3, 4)) #Unknown tuple

Подходящие словари:

Словари — это еще одна структура данных, с которой мы работаем и которую можно сопоставить с помощью структурного сопоставления с образцом. Мы можем сопоставлять шаблоны в словарях на основе их ключей, значений или того и другого.

Вот пример сопоставления словаря на основе его ключей:

def process_dict(dct):
    match dct:
        case {"name": "John", "age": 25}:
            print("Found dictionary with name John and age 25")
        case {"name": "Alice", "age": 30}:
            print("Found dictionary with name Alice and age 30")
        case {"name": "Bob", "age": 40}:
            print("Found dictionary with name Bob and age 40")
        case _:
            print("Unknown dictionary")

process_dict({"name": "John", "age": 25}) #Found dictionary with name John and age 25
process_dict({"name": "John"}) #Unknown dictionary

Подстановочные шаблоны:

Во всех предыдущих примерах мы использовали подстановочный знак по умолчанию. Шаблон подстановочного знака обозначается символом подчеркивания (_) и соответствует всему, что не соответствует ни одному из других шаблонов. Это похоже на случай по умолчанию в операторе case switch.

Мы также можем использовать подстановочный знак внутри случая, чтобы сопоставить все, что соответствует шаблону до этого момента:

def process_list(lst):
    match lst:
        case [1, _, 3]:
            print("Found list with 1 and 3")
        case [_, 2, _]:
            print("Found list with 2")
        case _:
            print("Unknown list")

process_list([1, 2, 3]) #Found list with 1 and 3
process_list([3, 2, 1]) #Found list with 2

Шаблоны защиты:

В дополнение к шаблону подстановочных знаков мы также можем использовать защитные шаблоны для соответствия более сложным условиям. Защитный шаблон — это шаблон, за которым следует логическое выражение. Логическое выражение оценивается только в том случае, если шаблон соответствует. Если выражение истинно, то выполняется соответствующий блок кода.

Вот пример использования шаблона защиты для сопоставления со словарем:

def process_dict(dct):
    match dct:
        case {"name": str, "age": int} if dct["age"] >= 18:
            print("Found dictionary with name and age, and age is greater than or equal to 18")
        case {"name": str, "age": int} if dct["age"] < 18:
            print("Found dictionary with name and age, and age is less than 18")
        case _:
            print("Unknown dictionary")

process_dict({"name": "Steve", "age": 28}) #Found dictionary with name and age, and age is less than 18
process_dict({"name": "Roger"}) #Unknown dictionary

Структурное сопоставление с образцом упрощает код и делает его более читабельным, устраняя необходимость в длинных операторах if-else или операторах switch-case. Кроме того, он позволяет создавать более выразительный код, предоставляя такие функции, как шаблоны подстановочных знаков и защитные шаблоны. С введением структурного сопоставления шаблонов Python стал еще более универсальным и мощным языком.

— — —

Как вы думаете, почему разработчики перешли на использование структурного сопоставления шаблонов в Python?

Потому что они устали от всех утверждений if-elif-else-if-elif-else, из-за которых им надоело принимать решения!

🙂🙂🙂