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

Как работают функции map(), filter() и reduce()?

2.0 Middle🔥 181 комментариев
#DevOps и инфраструктура#Django

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

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

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

Как работают функции map(), filter() и reduce()?

Общая идея: Функциональное программирование

map(), filter() и reduce() — это основные функции функционального программирования в Python. Они позволяют обрабатывать последовательности данных без явных циклов, применяя функцию к каждому элементу.

Это функции высшего порядка (higher-order functions) — они принимают другие функции как аргументы.

map() — Преобразование каждого элемента

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

# Синтаксис: map(function, iterable)
def square(x):
    return x ** 2

numbers = [1, 2, 3, 4, 5]
result = map(square, numbers)
print(list(result))  # [1, 4, 9, 16, 25]

# С лямбда-функцией
result = map(lambda x: x ** 2, numbers)
print(list(result))  # [1, 4, 9, 16, 25]

# Несколько итерируемых объектов
nums1 = [1, 2, 3]
nums2 = [10, 20, 30]
result = map(lambda x, y: x + y, nums1, nums2)
print(list(result))  # [11, 22, 33]

Как это работает внутри:

def my_map(func, iterable):
    """Упрощённая реализация map()"""
    for item in iterable:
        yield func(item)  # Ленивое вычисление!

numbers = [1, 2, 3]
result = my_map(lambda x: x * 2, numbers)
print(list(result))  # [2, 4, 6]

Важная особенность: map() возвращает итератор (ленивое вычисление), а не список. Это экономит память для больших последовательностей.

Альтернатива — list comprehension (более Pythonic):

# map() версия
result = list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))

# List comprehension версия (рекомендуется)
result = [x ** 2 for x in [1, 2, 3, 4, 5]]

filter() — Выборка элементов

filter() оставляет только элементы, для которых функция возвращает True.

# Синтаксис: filter(function, iterable)
def is_even(x):
    return x % 2 == 0

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = filter(is_even, numbers)
print(list(result))  # [2, 4, 6, 8, 10]

# С лямбда-функцией
result = filter(lambda x: x % 2 == 0, numbers)
print(list(result))  # [2, 4, 6, 8, 10]

# Фильтрация строк
words = ["python", "java", "c", "go", "rust"]
long_words = filter(lambda w: len(w) > 2, words)
print(list(long_words))  # ["python", "java", "rust"]

Если функция — None:

numbers = [0, 1, False, 2, "", 3, None, 4]
result = filter(None, numbers)
print(list(result))  # [1, 2, 3, 4] — убирает falsy значения

Как это работает внутри:

def my_filter(func, iterable):
    """Упрощённая реализация filter()"""
    for item in iterable:
        if func(item):  # Проверяем условие
            yield item

numbers = [1, 2, 3, 4, 5]
result = my_filter(lambda x: x > 2, numbers)
print(list(result))  # [3, 4, 5]

Альтернатива — list comprehension:

# filter() версия
result = list(filter(lambda x: x > 2, [1, 2, 3, 4, 5]))

# List comprehension версия (более Pythonic)
result = [x for x in [1, 2, 3, 4, 5] if x > 2]

reduce() — Сворачивание (accumulation)

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

⚠️ Важно: reduce() находится в модуле functools

from functools import reduce

# Синтаксис: reduce(function, iterable, [initializer])
def add(x, y):
    return x + y

numbers = [1, 2, 3, 4, 5]
result = reduce(add, numbers)
print(result)  # 15 (1+2+3+4+5)

# Эквивалент: 1 + 2 = 3, 3 + 3 = 6, 6 + 4 = 10, 10 + 5 = 15

# С лямбда-функцией
result = reduce(lambda x, y: x + y, numbers)
print(result)  # 15

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

Как это работает внутри:

def my_reduce(func, iterable, initializer=None):
    """Упрощённая реализация reduce()"""
    iterator = iter(iterable)
    
    if initializer is None:
        accumulator = next(iterator)
    else:
        accumulator = initializer
    
    for value in iterator:
        accumulator = func(accumulator, value)
    
    return accumulator

numbers = [1, 2, 3, 4]
result = my_reduce(lambda x, y: x + y, numbers)
print(result)  # 10

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

# Произведение чисел
from functools import reduce

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

# Нахождение максимума
from functools import reduce

numbers = [3, 1, 4, 1, 5, 9, 2, 6]
max_num = reduce(lambda x, y: x if x > y else y, numbers)
print(max_num)  # 9

# Объединение словарей
from functools import reduce

dicts = [{"a": 1}, {"b": 2}, {"c": 3}]
merged = reduce(lambda x, y: {**x, **y}, dicts)
print(merged)  # {"a": 1, "b": 2, "c": 3}

Цепочка: map → filter → reduce

Часто используются вместе:

from functools import reduce

# Задача: найти сумму квадратов чётных чисел
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# Вариант 1: map → filter → reduce
result = reduce(
    lambda x, y: x + y,
    filter(
        lambda x: True,  # Все оставшиеся
        map(
            lambda x: x ** 2,  # Возводим в квадрат
            filter(
                lambda x: x % 2 == 0,  # Только чётные
                numbers
            )
        )
    )
)
print(result)  # 2^2 + 4^2 + 6^2 + 8^2 + 10^2 = 4 + 16 + 36 + 64 + 100 = 220

# Вариант 2: List comprehension (более читаемо)
result = sum(x ** 2 for x in numbers if x % 2 == 0)
print(result)  # 220

map() vs. filter() vs. List Comprehension

ФункцияПримерКогда использовать
map()map(str, [1, 2, 3])Преобразование типов, редко (list comprehension лучше)
filter()filter(lambda x: x > 0, nums)Фильтрация, редко (list comprehension лучше)
reduce()reduce(lambda x, y: x+y, nums)Аккумуляция, свёртка данных
List comprehension[x*2 for x in nums]РЕКОМЕНДУЕТСЯ для map и filter

Ленивое вычисление (Lazy Evaluation)

map() и filter() возвращают итераторы, а не списки:

# Это НЕ вычисляется сразу!
result = map(lambda x: x ** 2, [1, 2, 3, 4, 5])
print(type(result))  # <class "map object">

# Вычисление происходит при итерации
for value in result:
    print(value)  # 1, 4, 9, 16, 25

# Или при конвертации в список
result = list(map(lambda x: x ** 2, [1, 2, 3]))
print(result)  # [1, 4, 9]

Это экономит память для больших данных!

Заключение

  • map() преобразует каждый элемент
  • filter() выбирает элементы по условию
  • reduce() сворачивает последовательность в одно значение
  • В Python рекомендуется использовать list comprehension вместо map/filter для читаемости
  • reduce() полезен для аккумуляции и свёртки данных
  • Все возвращают итераторы (ленивое вычисление) — это экономит память
Как работают функции map(), filter() и reduce()? | PrepBro