Pattern matching

Конструкция match

Последнее обновление: 01.02.2022

Начиная с версии 3.10 в языке Python появилась такая функциональность как pattern matching (сопоставление шаблонов). Pattern matching представляет применение конструкции match, которая позволяет сопоставить выражение с некоторым шаблоном. И если выражение соответствует шаблону, то выполняются определенные действия. В этом смысле конструкция match похожа на конструкцию if/else/elif, которая выполняет определенные действия в зависимости от некоторого условия. Однако функциональность match гораздо шире - она также позволяет извлечь данные из составных типов и применить действия к различным частям объектов.

Конструкция match имеет следующее формальное определение:

match выражение:
    case шаблон_1:
        действие_1
    case шаблон_2:
        действие_2
    ................
    case шаблон_N:
        действие_N
    case _:
        действие_по_умолчанию

После ключевого слова match идет сравниваемое выражение. И затем после двоеточия на последующих строках располагаются выражения case. После каждого выражения case указывается шаблон, с которым сравнивается выражение из match. После шаблона через двоеточие указываются набор выполняемых действий блока case.

Конструкция match последовательно сравнивает выражение с шаблонами из блоков case. И если был найден шаблон из какого-нибудь блока case соответствует выражению из match, то выполняются инструкции из данного блока case.

В качестве паттернов/шаблонов, с которыми сравниваются выражения, могут применяться как данные примитивных типов, так и последовательности элементов и объектов классов.

Вначале рассмотрим ситуацию, когда в качестве шаблона выступают литералы примитивных типов. Например, в зависимости от языка выведем приветственное сообщение:

def print_hello(language):
    match language:
        case "russian":
            print("Привет")
        case "english":
            print("Hello")
        case "german":
            print("Hallo")


print_hello("english")      # Hello
print_hello("german")       # Hallo
print_hello("russian")      # Привет

Здесь функция print_hello принимает параметр language, через который передается выбранный язык. В самой функции конструкция match сравнивает значение переменной language. В блоках case определяются шаблоны - строки, с которыми сопоставляется переменная language.

Например при вызове print_hello("english") параметр language равен "english", поэтому конструкция match выберет следующий блок case:

case "english":
    print("Hello")

Обратите внимание, что блоки case имеют отступы от начала конструкции match. А инструкции каждого блока case имеют отступы от начала данного блока case. Но если блок case имеет одну инстукцию, ее можно поместить на той же строке, что и оператор case:

def print_hello(language):
    match language:
        case "russian": print("Привет")
        case "english": print("Hello")
        case "german": print("Hallo")


print_hello("english")      # Hello
print_hello("german")       # Hallo
print_hello("russian")      # Привет

Причем если выражение из match не соответствует ни одному из шаблонов case, то соответственно ни один из этих блоков case не выполняется.

Если необходимо, чтобы при несовпадении значений (если ни один из шаблонов case не соответствует выражению match) выполнялись некоторые действия по умолчанию, то в этом случае применяется шаблон _ (прочерк):

def print_hello(language):
    match language:
        case "russian":
            print("Привет")
        case "english":
            print("Hello")
        case "german":
            print("Hallo")
        case _:
            print("Undefined")


print_hello("english")      # Hello
print_hello("spanish")      # Undefined

Если ни один из шаблонов case не соответствует значению language, то будет выполняться блок:

case _: 
    print("Undefined")

Но также можно определить блок case, который позволяет сравнивать сразу с несколькими знечениями. В этом случае значения разделяются вертикальной чертой:

def print_hello(language):
    match language:
        case "russian":
            print("Привет")
        case "american english" | "british english" | "english":
            print("Hello")
        case _:
            print("Undefined")


print_hello("english")              # Hello
print_hello("american english")     # Hello
print_hello("spanish")              # Undefined

В данном случае шаблон case "american english" | "british english" | "english" соответствует сразу трем значениям.

Подобным образом можно сравнивать выражения с данными других типов. Например:

def operation(a, b, code):
    match code:
        case 1:
            return a + b
        case 2:
            return a - b
        case 3:
            return a * b
        case _:
            return 0


print(operation(10, 5, 1))      # 15
print(operation(10, 5, 2))      # 5
print(operation(10, 5, 3))      # 50
print(operation(10, 5, 4))      # 0

Здесь функция operation принимает два числа и код операции. Конструкция match сравнивает код операции с конкретными значениями и в зависимости от значения выполняет на числами определенную операцию. Например, если code равен 1, то выполняется выражение:

case 1:
    return a + b

это выражение case возвратит из функцию сумму чисел a и b.

Аналогично если code = 2, то возвращается разность, а если code = 3, то возвращается произведение чисел. Во всех остальных случаях возвращается 0.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850