Как разработчики, мы часто используем наши любимые встроенные функции Python, а иногда даже пишем собственные решения для задач, для которых уже есть эффективные встроенные решения. Однако стандартная библиотека Python содержит множество скрытых возможностей, которые могут упростить наш код и повысить производительность.
В этой статье мы рассмотрим некоторые менее известные, но невероятно полезные функции Python, которые заслуживают большего внимания.
1. Эффективные операции с рассортированным списком для разделения пополам
Модуль bisect
помогает поддерживать отсортированные списки и эффективно находить точки вставки, что особенно полезно, когда вам нужен быстрый поиск или динамическая сортировка последовательностей.
Пример: Система отслеживания оценок
Давайте реализуем систему, которая поддерживает сортировку оценок, находит точки вставки и динамически определяет буквенные grades.
from bisect import bisect_left, bisect_right, insort grades = [60, 70, 75, 85, 90, 95] # Найдите правильную позицию для вставки новой grades new_grade = 82 position = bisect_left(grades, new_grade) print(f"Вставить 82 на позицию: {position}") # Вставить, сохраняя сортировку списка insort(grades, new_grade) print(f"grades после вставки: {grades}") # Присвоить буквенные grades в зависимости от балла def grade_to_letter(score): breakpoints = [60, 70, 80, 90] # F, D, C, B, A grades = 'FDCBA' position = bisect_right(контрольные точки, оценка) возвращает grades[позиция] print(f"Оценка 82 получает оценку: {grade_to_letter(82)}") print(f"Оценка 75 получает оценку: {grade_to_letter(75)}")
2. itertools.pairwise — простая обработка последовательных пар
Функция pairwise
генерирует последовательные пары в цепочке, что делает её отличной для анализа тенденций, вычисления разностей и сглаживания данных.
Пример: Анализ изменения температуры
pairwise
из модуля itertools позволяет нам без труда обрабатывать последовательные пары.
from itertools import pairwise temperatures = [20, 23, 24, 25, 23, 22, 20] # Вычислить разницу температур changes = [curr - prev for prev, curr in pairwise(temperatures)] print("Изменения температуры:", changes) # Вычислить скользящие средние moving_averages = [(t1 + t2) / 2 for t1, t2 in pairwise(temperatures)] print("Скользящие средние:", moving_averages) # Найти самый большой скачок температуры max_jump = max(abs(b - a) for a, b in pairwise(temperatures)) print(f"Самый большой скачок температуры: {max_jump} градусов")
3. statistics.fmean — быстрое и точное вычисление среднего значения с плавающей запятой
Функция fmean
вычисляет среднее значение быстрее и с более высокой точностью по сравнению с mean()
, что делает её отличным решением для больших наборов данных.
Пример: Сравнение скорости mean() и fmean()
В этом примере показано сравнение производительности двух функций из модуля статистики Python: mean()
и fmean()
.
from statistics import mean, fmean import time temperatures = [21,5, 22,1, 23,4, 22,8, 21,8] * 100000 # Обычное среднее арифметическое start_time = time.perf_counter() regular_mean = mean(temperatures) regular_time = time.perf_counter() - start_time # fmean start_time = time.perf_counter() fast_mean = fmean(temperatures) fast_time = time.perf_counter() - start_time print(f"Обычное среднее значение: {regular_mean:.10f} (заняло {regular_time:.4f} секунд)") print(f"fmean: {fast_mean:.10f} (заняло {fast_time:.4f} секунд)")
fmean
это значительно быстрее, особенно для больших наборов данных.
4. itertools.takewhile — процесс до тех пор, пока не будет выполнено условие
Функция takewhile
помогает обрабатывать последовательности до тех пор, пока не будет выполнено условие, предлагая более удобный способ прерывания циклов.
Пример: Обработка журналов До тех пор, пока не возникнет ошибка
В этом примере показано, как эффективно обрабатывать записи в журнале до тех пор, пока не возникнет ошибка, с помощью функции itertools.takewhile
в Python. Цель состоит в том, чтобы извлечь и отобразить все записи в журнале, которые появляются до первой записи с ошибкой в списке журналов.
from itertools import takewhile log_entries = [ "INFO: System started", "INFO: Loading data", "INFO: Processing users", "ERROR: Database connection failed", "INFO: Retrying connection", ] # Получаем журналы до первой ошибки normal_operation = list(takewhile(lambda x: x.startswith("ERROR"), log_entries)) print("Журналы до первой ошибки:") print("\n".join(normal_operation))
5. operator.attrgetter – эффективное извлечение атрибутов объекта
Функция attrgetter
упрощает извлечение атрибутов из объектов, особенно для сортировки и вложенных атрибутов.
Пример: Сортировка статей блога по авторам и просмотрам
Этот код демонстрирует, как отсортировать список статей в блоге по нескольким критериям с помощью функции sorted()
в Python и утилиты attrgetter из модуля operator.
Сортировка выполняется сначала по имени автора (в алфавитном порядке), а затем по количеству просмотров (в числовом порядке). Этот подход полезен, если вы хотите иерархически упорядочить данные, например, сгруппировать статьи по авторам и ранжировать их по популярности.
from operator import attrgetter from datetime import datetime class Article: def __init__(self, title, author, views, date): self.title = title self.author = author self.stats = type('Статистика', (), {'просмотров': views}) self.date = date def __repr__(self): return f"{self.title} от {self.author}" статьи = [ Article(«Советы по Python», «Алиса», 1500, дата (2025, 1, 15)), Article(«Наука о данных», «Боб», 2500, дата (2025, 1, 20)), Article(«Веб-разработка», «Алиса», 1800, дата (2025, 1, 10)) ] # Сортировка по автору, а затем по просмотрам sorted_articles = sorted(articles, key=attrgetter('author', 'stats.views')) для каждой статьи в sorted_articles: print(f"{article.author}: {article.title} ({article.stats.views} просмотров)")
6. itertools.chain.from_iterable — эффективное выравнивание вложенных списков
Функция itertools.chain.from_iterable
— это мощный инструмент в модуле itertools Python, который позволяет преобразовывать вложенные итерируемые структуры (например, списки списков, кортежи кортежей и т. д.) в один итерируемый объект с эффективным использованием памяти.
В отличие от других методов сглаживания, таких как генерация списков или вложенные циклы, chain.from_iterable
позволяет избежать создания промежуточных списков, что делает его особенно полезным для работы с большими наборами данных.
Пример: Приведение в соответствие данных о продажах
В этом примере показано, как эффективно сгладить вложенную структуру списков с помощью itertools.chain
. в Python. Сценарий включает в себя данные о продажах, представленные в виде списка подсписков, где каждый подсписок содержит кортежи, представляющие месячные показатели продаж.
Цель состоит в том, чтобы «сгладить» эту вложенную структуру, превратив её в единый список кортежей для упрощения обработки или анализа.
from itertools import chain sales_data = [ [('Январь', 100), ('Февраль', 150)], [('Март', 200), ('Апрель', 180)], [('Май', 210), ('Июнь', 190)] ] # Эффективно сглаживаем данные flat_sales = list(chain.from_iterable(sales_data)) print("Сглаженные данные о продажах:", flat_sales)
7. functools.cache – Автоматическое кэширование функций
Декоратор cache
(введённый в Python 3.9) сохраняет результаты функций для ускорения повторяющихся вычислений. Он идеально подходит для рекурсивных или ресурсоёмких вычислений.
Пример: Оптимизация последовательности Фибоначчи
Этот пример демонстрирует, как `functools.cache
` значительно повышает производительность за счёт сохранения ранее вычисленных результатов. Вместо пересчёта значений при каждом рекурсивном вызове он извлекает кэшированные результаты, что делает такие функции, как вычисления Фибоначчи, экспоненциально более быстрыми.
from functools import cache @cache def fibonacci(n): if n < 2: return n return fibonacci(n - 1) + fibonacci(n - 2) print(fibonacci(30)) # Гораздо быстрее, чем версия без кэширования
Результат:
832040
8. contextlib.suppress – Более Чистая обработка исключений
Функция suppress
— более чистая альтернатива try-except, когда вы хотите игнорировать определённые исключения без лишнего шаблонного кода.
Пример: Подавление ошибок «Файл не найден»
В этом примере выполняется попытка открыть файл, который может не существовать. Вместо того чтобы вызвать ошибку FileNotFoundError, функция suppress()
обрабатывает её без предупреждения, позволяя программе продолжить работу без прерывания.
from contextlib import suppress with suppress(FileNotFoundError): with open("non_existent_file.txt", "r") as file: data = file.read() print("Сбоя нет, программа продолжается")
Результат:
Сбоя нет, программа продолжается!
9. pathlib.Path.glob – интуитивно понятный поиск файлов
Метод glob()
из pathlib.Path
позволяет искать файлы, соответствующие определённому шаблону, в каталоге. Использование rglob()
позволяет выполнять рекурсивный поиск, то есть просматривать все подкаталоги, что полезно для таких задач, как поиск всех скриптов Python в папке проекта без ручной проверки каждого каталога.
Пример: Рекурсивный поиск всех файлов Python
В этом примере используется Path.rglob("*.py")
для рекурсивного поиска всех файлов Python (.py)
в текущем каталоге и его подкаталогах. В результате получается список путей к файлам, что упрощает управление несколькими скриптами Python одновременно.
из pathlib импортируйте путь python_files = list(Путь(".").rglob("*.py")) print("Найдены файлы Python:", python_files)
10. dataclasses.asdict — простое преобразование объектов в словари
Функция asdict()
из классов данных упрощает преобразование объектов в словари, делая их пригодными для сериализации в JSON или упрощая работу с ними.
Пример: Преобразование пользовательского объекта в JSON
Преобразует объект dataclass
в словарь, что упрощает его сериализацию в JSON.
from dataclasses import dataclass, asdict import json @dataclass class User: name: str age: int email: str user = User("Алиса", 30, "alice@example.com") user_dict = asdict(user) print(json.dumps(user_dict, indent=4)) # Легко преобразовать в JSON
Заключение
Эти менее известные функции Python упрощают сложные операции, повышая читаемость и эффективность. Попробуйте интегрировать их в свои проекты, и вы удивитесь, насколько чище и быстрее станет ваш код!