← Назад к вопросам

Что такое reduce?

2.0 Middle🔥 141 комментариев
#Python

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI30 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Reduce в функциональном программировании

Reduce (или fold) — это функция высшего порядка, которая применяет функцию累積ующе к элементам последовательности, сводя её к одному значению.

Концепция

Reduce берёт:

  1. Функцию (принимает два аргумента)
  2. Итерируемый объект (список, кортеж и т.д.)
  3. Начальное значение (опционально)

И возвращает одно скалярное значение.

Python пример

from functools import reduce

# Суммирование
numbers = [1, 2, 3, 4, 5]
result = reduce(lambda x, y: x + y, numbers)
print(result)  # 15

# Пошагово:
# Шаг 1: (1, 2) → 1 + 2 = 3
# Шаг 2: (3, 3) → 3 + 3 = 6
# Шаг 3: (6, 4) → 6 + 4 = 10
# Шаг 4: (10, 5) → 10 + 5 = 15

# С начальным значением
result = reduce(lambda x, y: x + y, numbers, 100)
print(result)  # 115 (100 + 1 + 2 + 3 + 4 + 5)

Синтаксис

reduce(function, iterable, initializer=None)

Если initializer не указан:

  • Первый элемент становится начальным значением
  • Итерация начинается со второго элемента

Практические примеры

1. Произведение элементов

numbers = [2, 3, 4, 5]
product = reduce(lambda x, y: x * y, numbers)
print(product)  # 120 (2*3*4*5)

# Или с initializer:
product = reduce(lambda x, y: x * y, numbers, 1)
print(product)  # 120

2. Максимальное значение

numbers = [3, 7, 2, 9, 1]
max_val = reduce(lambda x, y: x if x > y else y, numbers)
print(max_val)  # 9

3. Объединение строк

words = ["Hello", "World", "Python"]
result = reduce(lambda x, y: x + " " + y, words)
print(result)  # "Hello World Python"

4. Сплющивание (flattening) вложенного списка

nested = [[1, 2], [3, 4], [5, 6]]
flat = reduce(lambda x, y: x + y, nested)
print(flat)  # [1, 2, 3, 4, 5, 6]

Reduce в других языках

JavaScript

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, val) => acc + val, 0);
console.log(sum);  // 15

// accumulator, current value, index, array
const result = numbers.reduce((acc, val, idx) => {
    console.log(`Step ${idx}: ${acc} + ${val} = ${acc + val}`);
    return acc + val;
}, 0);

PySpark: reduceByKey для больших данных

from pyspark import SparkContext

sc = SparkContext("local", "reduce example")
rdd = sc.parallelize([("a", 1), ("b", 2), ("a", 3)])

# Сумма значений по ключам (map-reduce pattern)
result = rdd.reduceByKey(lambda x, y: x + y)
print(result.collect())  # [('a', 4), ('b', 2)]

Сравнение с другими методами

# REDUCE
numbers = [1, 2, 3, 4, 5]
result_reduce = reduce(lambda x, y: x + y, numbers)

# SUM (встроенная функция)
result_sum = sum(numbers)

# FOR LOOP
result_loop = 0
for n in numbers:
    result_loop += n

print(result_reduce == result_sum == result_loop)  # True

Когда использовать Reduce

Хорошо:

# Когда нужна кастомная агрегация
data = [5, 3, 8, 1]
weighted_sum = reduce(
    lambda acc, val: acc + val * weight,
    data,
    initial=0
)

# Когда работаешь с функциональным стилем
result = reduce(compose(func1, func2, func3), args)

Плохо (используй встроенные функции):

# ❌ Вместо reduce(lambda x, y: x + y, numbers)
sum(numbers)  # ✓ более понятно

# ❌ Вместо reduce(max, numbers)
max(numbers)  # ✓ встроено и быстрее

# ❌ Вместо reduce(lambda x, y: x + [y], [], numbers)
list(flatten(numbers))  # ✓ более читаемо

Reduce vs Map vs Filter

# MAP: преобразует каждый элемент
squared = list(map(lambda x: x**2, [1, 2, 3]))
print(squared)  # [1, 4, 9]

# FILTER: отбирает элементы по условию
evens = list(filter(lambda x: x % 2 == 0, [1, 2, 3, 4]))
print(evens)  # [2, 4]

# REDUCE: сводит все элементы к одному значению
product = reduce(lambda x, y: x * y, [1, 2, 3, 4])
print(product)  # 24

# Комбинация: sum of squares
numbers = [1, 2, 3, 4]
result = reduce(
    lambda acc, x: acc + x**2,
    numbers,
    0
)
print(result)  # 1 + 4 + 9 + 16 = 30

Reduce с именованной функцией

import operator
from functools import reduce

# Вместо лямбды, используй operator
numbers = [1, 2, 3, 4, 5]

result = reduce(operator.add, numbers)
print(result)  # 15

product = reduce(operator.mul, numbers)
print(result)  # 120

# или собственная функция
def accumulate_product(acc, val):
    return acc * val

product = reduce(accumulate_product, numbers, 1)
print(product)  # 120

Производительность

import timeit

# REDUCE vs SUM
numbers = list(range(1000000))

time_reduce = timeit.timeit(
    lambda: reduce(lambda x, y: x + y, numbers),
    number=10
)

time_sum = timeit.timeit(
    lambda: sum(numbers),
    number=10
)

print(f"Reduce: {time_reduce:.4f}s")
print(f"Sum: {time_sum:.4f}s")
# Sum обычно в 10x быстрее (оптимизирован на C)

Резюме

Reduce:

  • Применяет функцию накопительно к элементам
  • Сводит список к одному значению
  • Часть functools в Python
  • Основа map-reduce pattern в Big Data
  • Использование: кастомные агрегации, функциональное программирование
  • Для простых операций: используй sum(), max(), min() (они быстрее)