📖 Теория

⚡ Кратко: что важно

Урок повторяет модули time и collections (OrderedDict, Counter, deque, defaultdict), frozenset, functools.lru_cache, основы работы со словарями, передачу функций, lambda и парадигмы программирования.

Что запомнить: функцию передают без скобок; @lru_cache(maxsize=...) кэширует результаты; frozenset неизменяем и хешируем; OrderedDict управляет порядком через move_to_end() и popitem().

Топ-3 ошибки: передавать func() вместо ссылки func; забывать list() вокруг map/filter; пытаться изменить frozenset или использовать обычный set как ключ словаря.

Модуль time

time.time() возвращает количество секунд, прошедших с 1 января 1970 года (Unix-эпоха). time.sleep(n) приостанавливает выполнение программы на n секунд.

import time

start = time.time()
time.sleep(0.1)
print(f"Прошло {time.time() - start:.4f} сек")

Модуль collections

OrderedDict — словарь, который явно сохраняет порядок вставки и добавляет методы move_to_end() и popitem(last=False).

from collections import OrderedDict

od = OrderedDict()
od["a"] = 1
od["b"] = 2
od["c"] = 3
print(od.popitem(last=False))  # первый элемент
print(od)

move_to_end(key, last=True) перемещает элемент в конец; с last=False — в начало.

from collections import OrderedDict

queue = OrderedDict([("task1", "low"), ("task2", "high")])
queue.move_to_end("task2")
print(queue)

Кэш и LRU-кэш

Кэш хранит результаты вычислений, чтобы не считать их заново. functools.lru_cache автоматически запоминает последние maxsize результатов функции и удаляет редко используемые.

from functools import lru_cache

@lru_cache(maxsize=128)
def fibonacci(n):
    if n < 2:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

print(fibonacci(30))

frozenset

frozenset — неизменяемое множество. Его нельзя дополнить или уменьшить, зато оно хешируемо и может быть ключом словаря или элементом другого множества.

frozen = frozenset([1, 2, 3])
registry = {frozen: "allowed"}
print(registry[frozen])

Работа со словарями

Оператор in проверяет наличие ключа. Цикл for key in dict перебирает ключи, а .items() даёт пары. update() добавляет или заменяет несколько значений; del, pop(), popitem() и clear() удаляют элементы.

data = {"name": "Alice", "age": 30}
data["city"] = "Paris"
data.update({"age": 31, "email": "alice@example.com"})
if "city" in data:
    print(data["city"])
del data["email"]
print(data.popitem())

Передача функций как аргументов

Функции — объекты. Передавайте имя функции без скобок, чтобы внутри другой функции вызвать её саму, а не результат.

def square(x):
    return x * x

def apply(func, value):
    return func(value)

print(apply(square, 5))

Lambda-функции

lambda args: expression создаёт анонимную функцию из одного выражения. Удобна как короткий аргумент для sorted(), map(), filter().

numbers = [3, 1, 4, 1, 5]
print(sorted(numbers, key=lambda x: -x))
print(list(map(lambda x: x * 2, numbers)))

Парадигмы программирования

Python — мультипарадигменный язык. Основные стили: императивный, процедурный, объектно-ориентированный, функциональный и декларативный. Функциональный стиль делает упор на чистые функции и неизменяемые данные.

# функциональный подход: новый объект вместо изменения старого
numbers = [1, 2, 3]
doubled = [x * 2 for x in numbers]
print(doubled)
Проверить по документации: современные детали поведения встроенных функций, стандартной библиотеки и версии Python сверяйте с официальной документацией.