В качестве шаблонов также могут выступать массивы. Подобным шаблоны также могут содержать либо конкретные значения, либо переменные, которые передаются элементы массивов, либо символ прочерка _, если элемент массива не важен:
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"]