Следишь ли за обновлениями Java
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Функция высшего порядка
Функция высшего порядка (Higher-Order Function, HOF) — это функция, которая принимает другие функции как аргументы или возвращает функцию как результат. Это мощный инструмент функционального программирования для написания универсального и переиспользуемого кода.
Основной принцип
Вместо того, чтобы писать разные функции для разных задач, пишем обобщённую функцию, которая принимает поведение как параметр:
# ❌ Без HOF: дублирование кода
def sum_numbers(numbers):
total = 0
for n in numbers:
total += n
return total
def multiply_numbers(numbers):
total = 1
for n in numbers:
total *= n
return total
def concatenate_strings(strings):
result = ""
for s in strings:
result += s
return result
# ✅ С HOF: одна универсальная функция
from functools import reduce
import operator
def fold(sequence, operation, initial):
"""Универсальная функция высшего порядка"""
return reduce(operation, sequence, initial)
# Использование с разными функциями
sum_result = fold([1, 2, 3], operator.add, 0) # 6
mult_result = fold([1, 2, 3], operator.mul, 1) # 6
str_result = fold(['a', 'b', 'c'], operator.add, '') # 'abc'
Тип 1: Функция принимает функцию как аргумент
Пример 1: map() — преобразование каждого элемента
def square(x):
return x ** 2
def double(x):
return x * 2
numbers = [1, 2, 3, 4]
# Функция высшего порядка map
result1 = list(map(square, numbers)) # [1, 4, 9, 16]
result2 = list(map(double, numbers)) # [2, 4, 6, 8]
# Или через lambda
result3 = list(map(lambda x: x ** 3, numbers)) # [1, 8, 27, 64]
Пример 2: filter() — фильтрация элементов
def is_even(x):
return x % 2 == 0
def is_positive(x):
return x > 0
numbers = [-2, -1, 0, 1, 2, 3, 4]
# filter принимает функцию-условие
even_nums = list(filter(is_even, numbers)) # [0, 2, 4]
pos_nums = list(filter(is_positive, numbers)) # [1, 2, 3, 4]
Пример 3: sorted() с ключом
students = [
{'name': 'Alice', 'grade': 85},
{'name': 'Bob', 'grade': 92},
{'name': 'Charlie', 'grade': 78}
]
# Сортируем по разным ключам, используя HOF
by_grade = sorted(students, key=lambda s: s['grade'])
by_name = sorted(students, key=lambda s: s['name'])
by_grade_desc = sorted(students, key=lambda s: s['grade'], reverse=True)
Тип 2: Функция возвращает функцию
Пример 1: Функция-генератор функций
def make_multiplier(n):
"""Возвращает функцию, которая умножает на n"""
def multiplier(x):
return x * n
return multiplier
# Создаём специализированные функции
multiply_by_2 = make_multiplier(2)
multiply_by_10 = make_multiplier(10)
print(multiply_by_2(5)) # 10
print(multiply_by_10(5)) # 50
Пример 2: Декоратор (самая практичная HOF)
def timer_decorator(func):
"""Возвращает функцию, которая профилирует время выполнения"""
import time
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} выполнена за {end - start:.4f}с")
return result
return wrapper
# Используем декоратор
@timer_decorator
def slow_function():
time.sleep(1)
return "Done"
slow_function() # "slow_function выполнена за 1.0001с"
Пример 3: Частичное применение (Currying)
from functools import partial
def multiply(a, b):
return a * b
def add(a, b):
return a + b
# Создаём специализированные функции через partial
add_10 = partial(add, 10) # Фиксируем первый аргумент
multiply_by_5 = partial(multiply, 5)
print(add_10(5)) # 15
print(multiply_by_5(3)) # 15
Практические примеры
Пример 1: Валидатор-генератор
def make_validator(min_val, max_val):
"""Возвращает функцию для валидации чисел в диапазоне"""
def validate(value):
if not isinstance(value, (int, float)):
return False
return min_val <= value <= max_val
return validate
# Создаём разные валидаторы
age_validator = make_validator(0, 150)
percentage_validator = make_validator(0, 100)
print(age_validator(25)) # True
print(age_validator(200)) # False
print(percentage_validator(85)) # True
Пример 2: Композиция функций
def compose(*functions):
"""Возвращает функцию, которая применяет все функции по порядку"""
def composed(x):
result = x
for func in reversed(functions):
result = func(result)
return result
return composed
def add_one(x):
return x + 1
def double(x):
return x * 2
def square(x):
return x ** 2
# Комбинируем функции: (x+1)*2 затем ^2
transform = compose(square, double, add_one)
print(transform(3)) # ((3+1)*2)^2 = (4*2)^2 = 8^2 = 64
Пример 3: Pipeline обработки данных
def apply_pipeline(data, *transformers):
"""Применяет последовательность трансформаций"""
result = data
for transform in transformers:
result = transform(result)
return result
def clean_whitespace(text):
return text.strip()
def to_lowercase(text):
return text.lower()
def remove_punctuation(text):
import string
return text.translate(str.maketrans('', '', string.punctuation))
def split_words(text):
return text.split()
# Pipeline
text = " Hello, World!!! "
words = apply_pipeline(
text,
clean_whitespace,
to_lowercase,
remove_punctuation,
split_words
)
print(words) # ['hello', 'world']
Встроенные HOF в Python
map, filter, reduce
from functools import reduce
numbers = [1, 2, 3, 4, 5]
# map: преобразование
squares = list(map(lambda x: x ** 2, numbers)) # [1, 4, 9, 16, 25]
# filter: фильтрация
evens = list(filter(lambda x: x % 2 == 0, numbers)) # [2, 4]
# reduce: свёртка в одно значение
total = reduce(lambda x, y: x + y, numbers) # 15
sorted, min, max с ключом
data = [{'name': 'John', 'age': 30}, {'name': 'Jane', 'age': 25}]
# Все эти функции — HOF
oldest = max(data, key=lambda x: x['age'])
youngest = min(data, key=lambda x: x['age'])
sorted_by_name = sorted(data, key=lambda x: x['name'])
Лучшие практики
1. Используй встроенные HOF вместо циклов
# ❌ Плохо
result = []
for item in items:
if item > 0:
result.append(item * 2)
# ✅ Хорошо
result = list(map(lambda x: x * 2, filter(lambda x: x > 0, items)))
2. Создавай HOF для переиспользуемой логики
# ✅ Хорошо: одна функция для разных случаев
def apply_if(predicate, func):
def wrapper(x):
return func(x) if predicate(x) else x
return wrapper
3. Предпочитай декораторы для внедрения функциональности
# Вместо обёртывания в коде
@log_execution
@validate_input
def my_function(x):
pass
4. Используй typing для ясности
from typing import Callable, List
def apply_to_all(func: Callable[[int], int], items: List[int]) -> List[int]:
return [func(item) for item in items]
Функции высшего порядка — основа функционального программирования и позволяют писать более абстрактный, модульный и переиспользуемый код.