filter, map и reduce в Python: разбор простого примера

filter, map и reduce в Python: разбор простого примера

@python_quiz

Разберем этот квиз

Короткий пример, но он затрагивает важные детали работы встроенных функций: filter, map и functools.reduce. Разберём, что делает код и почему он выводит именно такую строку.

Исходный код

python

Пошаговый разбор

  1. nums = [[], [1], [1, 2]]

- Список из трёх элементов: пустой список, список длины 1 и список длины 2.

  1. filter(None, nums)

- filter с первым аргументом None удаляет все "ложные" значения.
- Пустой список → ложное значение → отфильтрован.
- Результат: итератор по [[1], [1, 2]].

  1. map(len, filter(None, nums))

- Применяет функцию len к каждому элементу оставшегося итератора.
- Длины: 1 и 2.
- list(...) превращает итератор в список: [1, 2].

  1. map(len, nums) для reduce

- Здесь берём длины всех элементов исходного nums: len([])=0, len([1])=1, len([1,2])=2 → итератор выдаёт 0, 1, 2.

  1. reduce(lambda a, b: a + b, map(len, nums), 0)

- reduce складывает элементы итератора, начиная со стартового значения 0 (инициализатор).
- Вычисление: 0 + 0 → 0; 0 + 1 → 1; 1 + 2 → 3.
- Итог: 3.

Итоговый print выводит сначала список [1, 2], затем число 3, разделённые пробелом — то есть: [1, 2] 3

Почему не TypeError?

Варианты с TypeError предполагают, что reduce мог бы упасть из‑за пустого итератора. reduce действительно выбрасывает TypeError, если итератор пуст и инициализатор не указан. В данном коде инициализатор указан (0), поэтому даже если бы map(len, nums) вернул пустой итератор, reduce вернул бы 0 вместо ошибки. Здесь же итератор не пуст, и исключение не возникает.

Анализ вариантов (кратко)

  • Вариант с выводом [1, 2] 3 — совпадает с объяснённой логикой: пустой список отфильтрован, длины оставшихся — [1,2], сумма длин всех элементов nums с инициализатором 0 даёт 3.
  • Варианты с [0, 1, 2] предполагают, что фильтрация не применялась при первом выводе; это неверно, потому что фильтр удалил пустой список.
  • Варианты с TypeError некорректны из‑за наличия инициализатора у reduce.

Современная альтернатива (короче и понятнее)

Для суммирования длин обычно удобнее использовать sum:

python

Этот вариант более питоничен и читабелен: list comprehension и sum хорошо читаются и не требуют import.

Вывод

Программа напечатает:
[1, 2] 3

Ключевые моменты: filter(None, ...) удаляет "пустые" значения, map(len, ...) даёт список длин, а reduce с указанным инициализатором безопасно суммирует даже при пустом итераторе.

Report Page