Menu
Русский

Списковые включения в Python: синтаксис, фильтрация и dict-comprehension

Списковые включения позволяют построить новый список в одну читаемую строку — отобразить, отфильтровать или и то, и другое — заменяя паттерн цикл + append.

Одна строка — одна идея

Ты уже писал этот паттерн несколько раз: начать с пустого списка, пройти по чему-то, может, отфильтровать и положить в результат.

main.py
Output
Click Run to see the output here.

Списковое включение говорит то же самое в одну строку:

main.py
Output
Click Run to see the output here.

Читается слева направо: «новый список, состоящий из n * 2 для каждого n в numbers». Структура — [expression for item in iterable].

Это не специфичный для Python трюк — его называют comprehension, потому что ты декларативно описываешь, что попадает в новый список, а не расписываешь механику сборки.

Добавляем фильтр

Добавь if после части с циклом — получишь фильтр:

main.py
Output
Click Run to see the output here.

Второе читается: «n * n для каждого n в numbers, но только если n нечётное».

Эквивалентный цикл:

main.py
Output
Click Run to see the output here.

Оба варианта нормальны. Включение короче и, когда прочтёшь несколько, реально быстрее сканируется глазом — намерение прямо в одной строке.

Map и filter одновременно

Можно пропустить значения через функцию и одновременно отфильтровать:

main.py
Output
Click Run to see the output here.

Для каждого слова длиннее 3 символов включаем его версию в верхнем регистре.

Вложенные циклы во включении

Два for-а дают пару в стиле декартова произведения:

main.py
Output
Click Run to see the output here.

Порядок такой же, как если бы ты вложил циклы: первый for — внешний, второй — внутренний. Читается слева направо, как и эквивалентный цикл с отступами.

Два уровня — примерно предел, после которого обычный цикл читается лучше. Дошёл до трёх — переключайся обратно на циклы.

Включения словарей и множеств

Та же идея, другие скобки:

main.py
Output
Click Run to see the output here.

Включения множеств на первый взгляд выглядят так же, как включения словарей, — разница в key: value против одного выражения. Фигурные плюс : — словарь; фигурные без : — множество.

Generator-выражения

Близнец спискового включения, но с круглыми скобками вместо квадратных — и, что критично, он не строит список:

main.py
Output
Click Run to see the output here.

Заметь: генератор мы передали прямо в sum() и any() — без лишних скобок. Generator-выражения — правильный инструмент, когда вызывающей стороне достаточно один раз проитерироваться. Для больших коллекций они экономят память по сравнению с полным списком.

Когда взять обычный цикл

Включения соблазнительны. Технически туда можно напихать много. Не стоит.

Тянись к обычному циклу, когда:

  • Преобразование состоит из нескольких шагов. Если нужны промежуточные переменные — распиши.
  • Есть сложная обработка ошибок или ветвление.
  • Любой читатель вынужден задержаться на строке дважды, чтобы её понять.

Правило, которое я применяю: если могу прочесть включение на одном вдохе и понять, что оно делает, — оно остаётся. Спотыкаюсь — переписываю в цикл.

Некоторые включения выглядят умно, но изматывают:

main.py
Output
Click Run to see the output here.

Результат тот же. Цикл — пять строк вместо одной, но «длиннее» ≠ «хуже».

Несколько паттернов, которые пригодятся

main.py
Output
Click Run to see the output here.

Эти пять паттернов покрывают удивительно большую долю повседневной работы с данными.

Дальше

Ты уже видел основные коллекционные типы и включение, которое их связывает. Следующая глава — функции: упаковка поведения в именованные, переиспользуемые единицы.

Часто задаваемые вопросы

Что такое списковое включение в Python?

Компактный синтаксис для построения нового списка из существующего итерируемого. [x * 2 for x in numbers] создаёт новый список, где каждое число удвоено. Можно и фильтровать: [x for x in numbers if x > 0].

Когда лучше не использовать списковое включение?

Когда страдает читаемость. Если выражение внутри сложное или глубоко вложенное — обычный for-цикл с нормальными именами переменных понятнее. Включения для простых преобразований — отображения и фильтрации. Всё, что сложнее, лучше в полном цикле.

В чём разница между списковым включением и generator-выражением?

Списковое включение строит весь список в памяти. Generator-выражение (тот же синтаксис, но в круглых скобках) выдаёт по одному элементу. Используй генератор, когда результаты передаются чему-то, что итерирует один раз — вроде sum(...) — чтобы не материализовать список, который тут же выбросишь.

Учитесь программировать с Coddy

НАЧАТЬ