Что такое функция высшего порядка
В Python функции — это полноценные объекты: их можно передавать в другие функции, возвращать из функций и сохранять в переменных. Функция высшего порядка принимает функцию как аргумент или возвращает функцию как результат.
def apply_twice(func: callable, value: int) -> int:
"""Применяет func к value дважды."""
return func(func(value))
def add_five(x: int) -> int:
return x + 5
print(apply_twice(add_five, 3)) # 13
Здесь apply_twice — функция высшего порядка, потому что её первый аргумент тоже функция.
Фильтрация: filter и предикаты
Предикат — функция, которая возвращает bool. Её можно передать в filter, чтобы оставить только нужные элементы.
def is_even(n: int) -> bool:
return n % 2 == 0
nums = [1, 2, 3, 4, 5, 6]
evens = list(filter(is_even, nums))
print(evens) # [2, 4, 6]
Функция filter возвращает итератор, поэтому результат обычно оборачивают в list() или обходят в цикле.
Лямбда-функции
lambda позволяет создать маленькую анонимную функцию прямо в месте использования. Она подходит, когда логика настолько простая, что отдельное def усложнит код.
nums = [1, 2, 3, 4, 5, 6]
evens = list(filter(lambda x: x % 2 == 0, nums))
print(evens) # [2, 4, 6]
def. Читаемость важнее краткости.
Агрегирование: reduce
Функция reduce из модуля functools последовательно применяет функцию к парам элементов и сворачивает коллекцию в одно значение.
from functools import reduce
numbers = [1, 2, 3, 4, 5]
product = reduce(lambda acc, x: acc * x, numbers, 1)
print(product) # 120
Третий аргумент 1 — начальное значение аккумулятора. Оно важно для пустых коллекций: без него reduce выбросит исключение.
Сортировка по ключу
Встроенная функция sorted принимает параметр key — функцию, которая вычисляет значение для сравнения. Это позволяет сортировать строки по длине, числа по абсолютной величине и так далее.
words = ["apple", "banana", "kiwi", "grape"]
sorted_words = sorted(words, key=len)
print(sorted_words) # ['kiwi', 'grape', 'apple', 'banana']
Функция len вызывается для каждого слова, и Python сортирует слова по полученным числам, а не по алфавиту.
Аннотации типов
Источник требует добавлять аннотации к решённым функциям. Аннотации не влияют на выполнение, но помогают IDE и статическим анализаторам находить ошибки.
from typing import Callable
def filter_numbers(
predicate: Callable[[int], bool],
numbers: list[int]
) -> list[int]:
return [n for n in numbers if predicate(n)]
Запись Callable[[int], bool] означает: функция, которая принимает один int и возвращает bool.
list[int], dict[str, int]. В более старых версиях для этого нужен модуль typing с заглавными именами: List[int], Dict[str, int].
Композиция функций
Несколько функций можно применять последовательно: результат одной передаётся в следующую. Этот приём используется в задании про цепочку шифрования.
def compose(value, *functions: callable):
for func in functions:
value = func(value)
return value
Такой подход делает цепочку преобразований явной и легко расширяемой.