Сопоставление структурных шаблонов для проверки наличия элемента в списке

Boto3 бесполезно перечисляет сегменты следующим образом:

{'Buckets': [{'CreationDate': datetime.datetime(1, 1, 1, 0, 0, tzinfo=tzlocal()),
              'Name': 'foo'},
             {'CreationDate': datetime.datetime(1, 1, 1, 0, 0, tzinfo=tzlocal()),
              'Name': 'bar'},
             {'CreationDate': datetime.datetime(2024, 7, 30, 15, 4, 59, 150000, tzinfo=tzlocal()),
              'Name': 'baz'}],
 'Owner': {...}}

Если я хочу знать, находится ли ведро foo в начале этого списка, я могу написать это:

match s3_response:
    case {"Buckets": [{"Name": "foo", "CreationDate": _}, *_]}:
        print("Bucket 'foo' found")
    case _:
        print("Bucket 'foo' not found")

И я могу придумать подобное решение, если известно, что ведро находится в конце.

А как насчет поиска ведра bar, которое находится в середине списка ведер? Вы можете надеяться, что сможете сделать это:

match s3_response:
    case {"Buckets": [*_, {"Name": "bar", "CreationDate": _}, *_]}:
        print("Bucket 'bar' found")
    case _:
        print("Bucket 'bar' not found")

Но это дает:

SyntaxError: несколько звездочек в шаблоне последовательности

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

'bar' in [bucket.get("Name", "") for bucket in s3_response.get("Buckets", [])]

В данном конкретном случае я мог бы использовать s3.head_bucket(Bucket = "bar"), но суть вопроса не в этом!

LondonRob 12.08.2024 21:41

Я думаю, это можно сделать только с помощью рекурсии (если вы хотите использовать match)

Andrej Kesely 12.08.2024 21:58

Хорошо, похоже, это не вариант использования match support. Спасибо за подтверждение. Странно, что вещи можно найти и в начале списков, и в конце, но не в середине!

LondonRob 12.08.2024 21:58

в любом случае - поддержка match звучит разумно - даже с синтаксисом «два *_». Вы можете попытаться начать обсуждение в официальном дискурсе Python по теме «идеи».

jsbueno 12.08.2024 22:10
обсудить.python.org/t/…
LondonRob 12.08.2024 22:34
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
5
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Выражение соответствия в операторах match..case в Python имеет специальный синтаксис, отличный от Python, поэтому все возможные совпадения ограничены тем, что указано в PEP-0622 .

И что там упоминается для последовательностей:

Шаблон последовательности выглядит как [a, *rest, b] и похож на список. распаковка. Важным отличием является то, что элементы, вложенные внутри это могут быть любые шаблоны, а не только имена или последовательности. Это соответствует только последовательностям соответствующей длины, если все подшаблоны также совпадают. Он делает все привязки своих подшаблоны.

Таким образом, для оператора in не существует эквивалента выражения соответствия — извините, что испортил вам удовольствие. Лучшее, что вы можете получить, — это использовать защитное выражение в вашем case, поскольку защитные выражения снова действительны в Python:

match s3_response:
    case {"Buckets": [*buckets] if any((bucket["Name"] == "bar" and "CreationDate" in bucket and len(bucket) == 2) for bucket in buckets):
        print("Bucket 'bar' found")

Я полагаю, вы всегда можете добавить вложенный цикл for, содержащий match/case под первым case, который ищет структуру, которую вы ищете.

LondonRob 12.08.2024 22:06

да. Я подумал об этом - в данном конкретном случае, я думаю, нужно извлечь значение buckets и выполнить for вне match...case .

jsbueno 12.08.2024 22:07

Другие вопросы по теме