Есть ли способ проверить, содержит ли Iterable шаблон, используя инструкцию python «match»?

Это связано с новой бета-версией Python 3.10 и новым matchсинтаксис. Есть ли способ проверить, содержится ли шаблон просто в итерируемом объекте? наиболее очевидное решение, просто поставить два символа подстановки с каждой стороны, но это вызывает SyntaxError из-за синтаксиса распаковки, возникающего при повторной распаковке.

Есть ли какой-нибудь способ сделать это? ПРИМЕЧАНИЕ: использование таких вещей, как классы-оболочки вокруг numbers в примере было бы хорошо, если он работает с использованием блоков совпадений и, по крайней мере, в некоторой степени читаем, но я уже пробовал это несколько и не имел особого успеха

пример:

      numbers = [1, 2, 3, 5, 7, 8, 9] #does not have to be a list, could be a class if needed

match numbers:
    # this just raises a SyntaxError, but I need a way to do something equivalent to this
    case [*_, (5 | 6), *_]:
        print("match!")

2 ответа

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

Лучший способ переписать ваш пример на легальном языке Python - это выполнить обычный тест:

      if any(i in (5, 6) for i in numbers):
    print("match!")

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

      match something:
    case [pattern, capturing, numbers] if any(i in (5, 6) for i in numbers):
        print("match!")

Конечно, если у вас есть последовательность , также можно найти элемент по известному индексу:

      match numbers:
    case [_, _, _, 5 | 6, *_]:
        print("match at position 3!")
    case [*_, 5 | 6, _, _, _]:
        print("match at position -4!")

С учетом сказанного ...

использование таких вещей, как классы-оболочки вокруг numbers в примере будет нормально, если он работает с использованием блоков совпадений и хотя бы в некоторой степени читается

... Я полагаю, что для этой работы можно взломать шаблоны сопоставления (при условии, что все ваши элементы хешируются и не имеют необычных правил равенства):

      match dict.fromkeys(numbers):
    case {5: _} | {6: _}:
        print("match!")

Я настоятельно рекомендую if форма над этим, тем не менее.

Я совсем не уверен в этом, но это работает со списком. Не стесняйтесь поправлять меня, и я удалю решение.

      numbers = [1, 2, 3, 5, 7, 8, 9]
match numbers:
    case [*num] if any(i in num for i in (5, 6)):
        print("match!")
Другие вопросы по тегам