Python: Проверка окончания строки одной из строк из списка

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для проверки совпадения окончания строки с одним из заданных подстрок используйте метод str.endswith(), который принимает кортеж:

Python
Скопировать код
variants = ('.txt', '.doc', '.pdf')
file_name = 'report.doc'
if file_name.endswith(variants):
    print('Всё в порядке, формат файла соответствует!')

Таким образом, осуществляется сравнение строки file_name с кортежем заданных расширений variants, что позволяет удостовериться в корректности формата файла.

Кинга Идем в IT: пошаговый план для смены профессии

Расширенный ответ

Игнорирование регистра в процессе проверки

Если вам необходимо провести проверку без учета регистра:

Python
Скопировать код
variants = ('.txt', '.doc', '.pdf')
file_name = 'report.DOC'
if file_name.lower().endswith(variants):
    print('Не беспокойтесь, формат файла правилен!')

Метод lower(), применённый к переменной file_name, обеспечивает сравнение строк без учета регистра символов.

Использование регулярных выражений для проверки сложных шаблонов

Регулярные выражения незаменимы для работы с более сложными шаблонами:

Python
Скопировать код
import re

variants = ['\.txt$', '\.doc$', '\.pdf$']
file_name = 'archive.pdf'

if any(re.search(pattern, file_name, re.IGNORECASE) for pattern in variants):
    print('Отлично, формат файла подтверждён!')

Флаг re.IGNORECASE как раз и позволяет выполнять поиск без учета регистра, а регулярные выражения идеально подходят для поиска сложных шаблонов.

Анализ производительности кода с помощью модуля timeit

Хотите измерить скорость выполнения вашего кода? Воспользуйтесь модулем timeit:

Python
Скопировать код
import timeit

# Честное сравнение производительности методов
timeit.timeit("file_name.lower().endswith(variants)", setup="file_name = 'example.DOC'; variants = ('.txt', '.doc', '.pdf')", number=10000)
timeit.timeit("any(re.search(pattern, file_name, re.IGNORECASE) for pattern in variants)", setup="import re; file_name = 'example.DOC'; variants = ['\.txt$', '\.doc$', '\.pdf$']", number=10000)

Выбирайте подход, оптимальный с точки зрения равновесия быстродействия и читаемости кода.

Эффективная проверка большого количества строк

Если вам нужно проверить множество строк, необходимо оптимизировать процесс:

Python
Скопировать код
def is_valid_format(file_name, extensions):
    return file_name.lower().endswith(tuple(extensions))

file_list = ['lord_of_the_rings.doc', 'harry_potter.jpg', 'game_of_thrones.pdf']
valid_formats = ('.txt', '.doc', '.pdf')

valid_docs = filter(lambda f: is_valid_format(f, valid_formats), file_list)
print(list(valid_docs))

Применение функции filter в сочетании с лямбда-функцией обеспечивает быстрое создание списка файлов в корректном формате.

Визуализация

Представьте набор возможных расширений файлов (в качестве целей) и строки, которые мы проверяем на совпадение с этими расширениями (как игроки):

Markdown
Скопировать код
Расширения: ['.com', '.net', '.org']

Допустим, это строки, которые мы хотим проверить на достижение правильной цели:

Python
Скопировать код
site_address = "Welcome to stackpython.org"

Исполнительная строка – словно игрок, стремящийся к цели:

Markdown
Скопировать код
Игрок: Welcome to stackpython.org
Цель: ⚽--->.org ✔️

Если строка "достигает цели" с нужным расширением, значит, мы получили корректное совпадение:

Markdown
Скопировать код
"Прошла" ли строка через ".com", ".net" или ".org"?
⚽ stackpython.org---> Цель!.org --> Да, прошла! 🎉

За пределами базового уровня

Разделение имени файла и его расширения

С задачей разделения имени файла и его расширения прекрасно справляется метод os.path.splitext:

Python
Скопировать код
import os

file_name = 'example.doc'
root, ext = os.path.splitext(file_name)

if ext in variants:
    print('Гол! Файл имеет корректное расширение.')

Такой подход гарантирует точное извлечение расширения, делая вас настоящим мастером своего дела!

Использование идиоматического кода на Python

Идиоматический код на Python живёт по принципу «Меньше значит лучше». Замените обычные циклы for на:

Python
Скопировать код
# Списковое включение — вариант, когда краткость действительно важнее!
is_valid = any(file_name.lower().endswith(ext) for ext in variants)

Замена циклов на списковые включения улучшает читаемость кода, а ваши коллеги будут вам благодарны за чистоту кода на этапе code review.

Полезные материалы

  1. Встроенные типы — документация Python 3.12.2 – раздел про метод str.endswith() Python.
  2. Встроенные функции — документация Python 3.12.2 – обзор функции any() Python.
  3. Когда стоит использовать списковое включение в Python — Real Python – применение списковых включений Python для оптимизации кода.
  4. Методы строк Python – полный перечень методов для работы со строками в Python.
  5. Как работают срезы в Python — Stack Overflow – проработка принципов работы срезов в Python.
  6. Как использовать лямбда-функции в Python — Real Python – познавательное руководство по использованию лямбда-функций в Python.
  7. Python Tutorial: Итераторы и итерируемые объекты — что это такое и как они работают? — YouTube — учебное видео, объясняющее принципы работы итераторов и итерируемых объектов в Python.