📝 Python

reduce() — Сверни всё в одно! 🔽

0
Author
04e5cc8b-58ac-4bdc-bdee-661bbb
📅
Published
03.04.2026
⏱️
Reading time
8 min
👁️
Views
10
🌱
Level
Beginner

Что такое reduce()?

reduce() сворачивает список в одно значение, применяя функцию последовательно.

Без reduce() (старый способ):

numbers = [1, 2, 3, 4, 5]

# Сумма всех чисел
total = 0
for num in numbers:
    total = total + num

print(total)  # 15

С reduce() (элегантно!):

from functools import reduce

numbers = [1, 2, 3, 4, 5]

total = reduce(lambda acc, x: acc + x, numbers)

print(total)  # 15

Одна строка вместо цикла с аккумулятором! 🚀


Синтаксис reduce()

from functools import reduce

reduce(функция, итерируемый_объект, начальное_значение)

Параметры:
- функция — принимает 2 аргумента: аккумулятор и текущий элемент
- итерируемый_объект — список, кортеж и т.д.
- начальное_значение — опциональное начальное значение аккумулятора

Возвращает: Единственное значение (не список!)


Как работает reduce()?

Визуализация:

from functools import reduce

numbers = [1, 2, 3, 4, 5]

result = reduce(lambda acc, x: acc + x, numbers)

Шаг за шагом:

Шаг 1: acc=1, x=2 → 1 + 2 = 3
Шаг 2: acc=3, x=3 → 3 + 3 = 6
Шаг 3: acc=6, x=4 → 6 + 4 = 10
Шаг 4: acc=10, x=5 → 10 + 5 = 15

Результат: 15

Аккумулятор (acc) — переменная, которая накапливает результат!


Базовые примеры

1. Сумма чисел

from functools import reduce

numbers = [1, 2, 3, 4, 5]

total = reduce(lambda acc, x: acc + x, numbers)
print(total)  # 15

# С начальным значением
total = reduce(lambda acc, x: acc + x, numbers, 10)
print(total)  # 25 (10 + 1 + 2 + 3 + 4 + 5)

2. Произведение чисел

numbers = [1, 2, 3, 4, 5]

product = reduce(lambda acc, x: acc * x, numbers)
print(product)  # 120 (1 * 2 * 3 * 4 * 5 = факториал!)

# С начальным значением 1
product = reduce(lambda acc, x: acc * x, numbers, 1)
print(product)  # 120

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

numbers = [5, 12, 3, 18, 25, 7]

maximum = reduce(lambda acc, x: acc if acc > x else x, numbers)
print(maximum)  # 25

4. Минимальное число

numbers = [5, 12, 3, 18, 25, 7]

minimum = reduce(lambda acc, x: acc if acc < x else x, numbers)
print(minimum)  # 3

reduce() со строками

Конкатенация строк

words = ["Python", "is", "awesome"]

sentence = reduce(lambda acc, word: acc + " " + word, words)
print(sentence)  # "Python is awesome"

# Лучше с начальным значением
sentence = reduce(lambda acc, word: acc + " " + word, words, "")
print(sentence.strip())  # "Python is awesome" (убрали пробел в начале)

Склеивание с разделителем

words = ["apple", "banana", "orange"]

# С запятыми
result = reduce(lambda acc, word: f"{acc}, {word}", words)
print(result)  # "apple, banana, orange"

# Или просто используй join! (проще)
result = ", ".join(words)
print(result)  # "apple, banana, orange"

reduce() со словарями

Суммирование значений

sales = [
    {"product": "Phone", "revenue": 500},
    {"product": "Laptop", "revenue": 1200},
    {"product": "Mouse", "revenue": 25}
]

total_revenue = reduce(lambda acc, sale: acc + sale["revenue"], sales, 0)
print(total_revenue)  # 1725

Объединение словарей

dicts = [
    {"a": 1},
    {"b": 2},
    {"c": 3}
]

merged = reduce(lambda acc, d: {**acc, **d}, dicts, {})
print(merged)  # {'a': 1, 'b': 2, 'c': 3}

Подсчёт элементов

items = ["apple", "banana", "apple", "orange", "banana", "apple"]

# Подсчитать каждый элемент
count = reduce(
    lambda acc, item: {**acc, item: acc.get(item, 0) + 1},
    items,
    {}
)
print(count)  # {'apple': 3, 'banana': 2, 'orange': 1}

Начальное значение (важно!)

Без начального значения:

numbers = [1, 2, 3, 4, 5]

result = reduce(lambda acc, x: acc + x, numbers)
# acc начинается с первого элемента (1)
print(result)  # 15

С начальным значением:

numbers = [1, 2, 3, 4, 5]

result = reduce(lambda acc, x: acc + x, numbers, 0)
# acc начинается с 0
print(result)  # 15

Когда начальное значение ОБЯЗАТЕЛЬНО?

1. Пустой список:

# БЕЗ начального — ОШИБКА!
result = reduce(lambda acc, x: acc + x, [])
# ❌ TypeError: reduce() of empty sequence with no initial value

# С начальным — ОК
result = reduce(lambda acc, x: acc + x, [], 0)
print(result)  # 0

2. Другой тип результата:

numbers = [1, 2, 3, 4, 5]

# Суммируем в словарь
result = reduce(
    lambda acc, x: {**acc, str(x): x ** 2},
    numbers,
    {}  # ← ОБЯЗАТЕЛЬНО! Результат — словарь
)
print(result)  # {'1': 1, '2': 4, '3': 9, '4': 16, '5': 25}

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

Пример 1: Факториал

def factorial(n):
    return reduce(lambda acc, x: acc * x, range(1, n + 1), 1)

print(factorial(5))  # 120 (1 * 2 * 3 * 4 * 5)
print(factorial(0))  # 1 (правильно!)

Пример 2: Сглаживание списка (flatten)

nested = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]

flattened = reduce(lambda acc, lst: acc + lst, nested, [])
print(flattened)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Пример 3: Пайплайн функций

def add_10(x):
    return x + 10

def multiply_2(x):
    return x * 2

def square(x):
    return x ** 2

# Применить все функции последовательно
functions = [add_10, multiply_2, square]
result = reduce(lambda acc, func: func(acc), functions, 5)
# 5 → add_10 → 15 → multiply_2 → 30 → square → 900
print(result)  # 900

Пример 4: Найти самый длинный элемент

words = ["cat", "elephant", "dog", "hippopotamus"]

longest = reduce(
    lambda acc, word: word if len(word) > len(acc) else acc,
    words
)
print(longest)  # "hippopotamus"

reduce() vs sum() / max() / min()

Для простых операций есть встроенные функции!

numbers = [1, 2, 3, 4, 5]

# reduce
total = reduce(lambda acc, x: acc + x, numbers)

# sum (ПРОЩЕ!)
total = sum(numbers)

print(total)  # 15

Когда использовать reduce():

  • ✅ Сложная логика (не просто сумма/max/min)
  • ✅ Нестандартные операции
  • ✅ Пайплайн преобразований

Когда НЕ использовать:

  • ❌ Сумма → используй sum()
  • ❌ Максимум → используй max()
  • ❌ Минимум → используй min()
  • ❌ Склеивание строк → используй "".join()

reduce() с обычной функцией

Lambda не обязательна! Можно использовать обычную функцию:

def add(acc, x):
    """Функция сложения для reduce."""
    print(f"acc={acc}, x={x}, result={acc + x}")
    return acc + x

numbers = [1, 2, 3, 4, 5]
result = reduce(add, numbers)

# Вывод:
# acc=1, x=2, result=3
# acc=3, x=3, result=6
# acc=6, x=4, result=10
# acc=10, x=5, result=15

print(result)  # 15

Полезно для отладки!


Комбинация reduce + map + filter

Функциональное программирование в действии!

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Чётные → удвоить → сумма
result = reduce(
    lambda acc, x: acc + x,
    map(lambda x: x * 2, filter(lambda x: x % 2 == 0, numbers)),
    0
)
print(result)  # 60

# Пошагово:
# filter: [2, 4, 6, 8, 10]
# map: [4, 8, 12, 16, 20]
# reduce: 4 + 8 + 12 + 16 + 20 = 60

Читается справа налево!


Распространённые ошибки

Ошибка 1: Забыли импортировать

# ❌ ОШИБКА
result = reduce(lambda acc, x: acc + x, [1, 2, 3])
# NameError: name 'reduce' is not defined

# ✅ ПРАВИЛЬНО
from functools import reduce
result = reduce(lambda acc, x: acc + x, [1, 2, 3])

Ошибка 2: Функция не возвращает значение

def add_bad(acc, x):
    acc + x  # Забыли return!

result = reduce(add_bad, [1, 2, 3])
print(result)  # None  ← Ошибка!

# ✅ ПРАВИЛЬНО
def add_good(acc, x):
    return acc + x

result = reduce(add_good, [1, 2, 3])
print(result)  # 6

Ошибка 3: Пустой список без начального значения

# ❌ ОШИБКА
result = reduce(lambda acc, x: acc + x, [])
# TypeError: reduce() of empty sequence with no initial value

# ✅ ПРАВИЛЬНО
result = reduce(lambda acc, x: acc + x, [], 0)
print(result)  # 0

Ошибка 4: Неправильный порядок аргументов

# ❌ ОШИБКА
result = reduce(lambda x, acc: acc + x, [1, 2, 3])
# Порядок важен! Первый аргумент — АККУМУЛЯТОР

# ✅ ПРАВИЛЬНО
result = reduce(lambda acc, x: acc + x, [1, 2, 3])

Альтернативы reduce()

Вместо reduce для суммы:

numbers = [1, 2, 3, 4, 5]

# reduce
total = reduce(lambda acc, x: acc + x, numbers, 0)

# sum (ЛУЧШЕ!)
total = sum(numbers)

Вместо reduce для max:

numbers = [5, 12, 3, 18, 25]

# reduce
maximum = reduce(lambda acc, x: acc if acc > x else x, numbers)

# max (ЛУЧШЕ!)
maximum = max(numbers)

Вместо reduce для сложных случаев:

# reduce
result = reduce(lambda acc, x: {**acc, x: x ** 2}, [1, 2, 3], {})

# dict comprehension (ЛУЧШЕ!)
result = {x: x ** 2 for x in [1, 2, 3]}

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

reduce() быстрый, но не всегда самый быстрый!

import time

numbers = list(range(1000000))

# reduce
start = time.time()
result1 = reduce(lambda acc, x: acc + x, numbers, 0)
time_reduce = time.time() - start

# sum (встроенная функция)
start = time.time()
result2 = sum(numbers)
time_sum = time.time() - start

print(f"reduce: {time_reduce:.4f}s")
print(f"sum: {time_sum:.4f}s")
# sum обычно БЫСТРЕЕ в 2-3 раза!

Встроенные функции оптимизированы!


Резюме

reduce() — это:

  • ✅ Свернуть список в одно значение
  • ✅ Использует аккумулятор
  • ✅ Применяет функцию последовательно
  • ✅ Функция принимает (аккумулятор, элемент)
  • ✅ Нужно импортировать: from functools import reduce

Синтаксис:

from functools import reduce

reduce(lambda acc, x: ..., data, initial_value)

Типичное использование:

# Сумма
reduce(lambda acc, x: acc + x, numbers, 0)

# Произведение
reduce(lambda acc, x: acc * x, numbers, 1)

# Максимум
reduce(lambda acc, x: acc if acc > x else x, numbers)

# Объединение
reduce(lambda acc, lst: acc + lst, nested_lists, [])

Когда НЕ использовать:

  • ❌ Простая сумма → sum()
  • ❌ Максимум/минимум → max() / min()
  • ❌ Склеивание строк → "".join()

Что дальше?

Теперь ты знаешь reduce()! 🎉

Следующие темы:
- List comprehensions — альтернатива map/filter
- Pure functions — функции без побочных эффектов
- Pipeline — цепочка map → filter → reduce

Святая троица функционального программирования:
1. map() — преобразовать каждый элемент
2. filter() — отобрать элементы
3. reduce() — свернуть в одно значение

Вместе они — сила! 🚀

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

JSON: Сохранение данных как в большой игре 💾

Цель: Научиться сохранять и загружать данные в формате JSON.

📅 03.04.2026 👁️ 10
📝

map() — Преобразуй всё разом! 🔄

map() применяет функцию к каждому элементу списка и возвращает результаты.

📅 03.04.2026 👁️ 7
📝

filter() — Отбери лучшее! 🔍

filter() отбирает элементы, которые проходят проверку (возвращают True).

📅 03.04.2026 👁️ 10

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!