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

Пошаговый разбор
- nums = [[], [1], [1, 2]]
- Список из трёх элементов: пустой список, список длины 1 и список длины 2.
- filter(None, nums)
- filter с первым аргументом None удаляет все "ложные" значения.
- Пустой список → ложное значение → отфильтрован.
- Результат: итератор по [[1], [1, 2]].
- map(len, filter(None, nums))
- Применяет функцию len к каждому элементу оставшегося итератора.
- Длины: 1 и 2.
- list(...) превращает итератор в список: [1, 2].
- map(len, nums) для reduce
- Здесь берём длины всех элементов исходного nums: len([])=0, len([1])=1, len([1,2])=2 → итератор выдаёт 0, 1, 2.
- 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:

Этот вариант более питоничен и читабелен: list comprehension и sum хорошо читаются и не требуют import.
Вывод
Программа напечатает:
[1, 2] 3
Ключевые моменты: filter(None, ...) удаляет "пустые" значения, map(len, ...) даёт список длин, а reduce с указанным инициализатором безопасно суммирует даже при пустом итераторе.