Массивы в pattern matching

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

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

def print_people(people):
    match people:
        case ["Tom", "Sam", "Bob"]:
            print("default people")
        case ["Tom", second, _]:
            print(f"Second Person: {second}")
        case [first, second, third]:
            print(f"{first}, {second}, {third}")


print_people(["Tom", "Sam", "Bob"])         # default people
print_people(["Tom", "Mike", "Bob"])        # Second Person: Mike
print_people(["Alice", "Bill", "Kate"])     # Alice, Bill, Kate
print_people(["Tom", "Kate"])               # несоответствует ни одному из шаблонов

В данном случае функция print_people принимает массив, который, как предполагается, состоит из трех элементов.

Первый шаблон предполагает, что элементы массива имеют определенные значения:

case ["Tom", "Sam", "Bob"]:
    print("default people")

В данном случае первый элемент массива должен представлять строку "Tom", второй - строку "Sam" и третий - строку "Bob".

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

case ["Tom", second, _]:
    print(f"Second Person: {second}")

При этом значение второго элемента передается в переменную second, а значение третьего элемента не важно, поэтому вместо него применяется прочерк.

Третий шаблон соответствует любому массиву из трех элементов. При этом его элементы передаются в переменные first, second и third:

case [first, second, third]:
    print(f"{first}, {second}, {third}")

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

def print_people(people):
    match people:
        case [_]:
            print("Массив из одного элемента")
        case [_, _]:
            print("Массив из двух элементов")
        case [_, _, _]:
            print("Массив из трех элементов")
        case _:
            print("Непонятно")


print_people(["Tom"])                   # Массив из одного элемента
print_people(["Tom", "Sam"])            # Массив из двух элементов
print_people(["Tom", "Sam", "Bob"])     # Массив из трех элементов
print_people("Tom")                     # Непонятно

Массивы неопределенной длины

Если необходимо сравнивать выражение с массивом неопределенной длины, то можно определить значения/переменные только для обязательных элементов массива, а на необязательные ссылаться с помощью символа * (звездочки):

def print_people(people):
    match people:
        case [first, *other]:
            print(f"First: {first}  Other: {other}")


print_people(["Tom"])                   # First: Tom  Other: []
print_people(["Tom", "Sam"])            # First: Tom  Other: ["Sam"]
print_people(["Tom", "Sam", "Bob"])     # First: Tom  Other: ["Sam", "Bob"]

В примере выше применяется параметр *other, который соответствует всем остальным элементам. То есть шаблон [first, *other] соответствует любому массиву, который имеет как минимум один элемент, и этот элемент будет помещаться в параметр first. Все остальные элементы помещаются в параметр other, который представляет массив значений.

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

def print_people(people):
    match people:
        case [first, *_]:
            print(f"First: {first}")


print_people(["Tom"])                   # First: Tom
print_people(["Sam", "Tom"])            # First: Sam
print_people(["Bob", "Sam", "Tom"])     # First: Bob

Альтернативные значения

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

def print_people(people):
    match people:
        case ["Tom" | "Tomas" | "Tommy", "Sam", "Bob"]:
            print("default people")
        case [first, second, third]:
            print(f"{first}, {second}, {third}")


print_people(["Tom", "Sam", "Bob"])         # default people
print_people(["Tomas", "Sam", "Bob"])       # default people
print_people(["Alice", "Bill", "Kate"])     # Alice, Bill, Kate

В данном случае первый шаблон соответствует массиву из трех элементов, где первый элемент равен или "Tom", или "Tomas", или "Tommy".

Также можно задать альтернативные значения для отдельных элементов, но и альтернативные массивы:

def print_people(people):
    match people:
        case ["Tom", "Sam", "Bob"] | ["Tomas", "Sam", "Bob"]:
            print("Tom/Tomas, Sam, Bob")
        case [first, second, third]:
            print(f"{first}, {second}, {third}")


print_people(["Tom", "Sam", "Bob"])         # Tom/Tomas, Sam, Bob
print_people(["Tomas", "Sam", "Bob"])       # Tom/Tomas, Sam, Bob
print_people(["Alice", "Bill", "Kate"])     # Alice, Bill, Kate

В данном случае первый шаблон будет соответствовать двум массивам: ["Tom", "Sam", "Bob"] и ["Tomas", "Sam", "Bob"]

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