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

К концу этого разбора вы сможете переписать цикл, который наполняет список, в одну строку — так пишут большинство Python-разработчиков. Уйдёт минут пятнадцать. Всё показано на Python 3.10+, но списковые включения работают одинаково начиная с Python 3.0, так что версия почти не важна.
Списковое включение (list comprehension) — короткий способ создать список на основе другого списка, диапазона или любого итерируемого объекта. Вместо трёх строк с append получается одна.
Что нужно до начала
Ничего, кроме установленного Python и места, где запускать код. Проверьте версию:
python --version
# Должно быть Python 3.6 или выше — подойдёт любая современнаяЗапускать примеры удобнее всего в интерактивной оболочке: наберите python в терминале и вставляйте строки по одной. После каждого выражения оболочка сразу покажет результат — это удобно для проверки.
Шаг 1. Сравните обычный цикл и включение
Задача простая: получить список квадратов чисел от 0 до 4. Сначала — как это делают через обычный цикл:
squares = []
for number in range(5):
squares.append(number ** 2)
print(squares)
# [0, 1, 4, 9, 16]А теперь то же самое одним списковым включением:
squares = [number ** 2 for number in range(5)]
print(squares)
# [0, 1, 4, 9, 16]Проверка: обе версии печатают одинаковую строку [0, 1, 4, 9, 16]. Если у вас так — вы уже написали своё первое включение.
Читается справа налево по смыслу: «пройди по range(5), для каждого number посчитай number ** 2 и собери всё в список».
Из чего состоит выражение
Любое списковое включение — это квадратные скобки, внутри которых три части:
- выражение — что положить в список (
number ** 2); - for-часть — откуда брать значения (
for number in range(5)); - необязательное условие — фильтр, о нём ниже.
Шаг 2. Добавьте условие-фильтр
Часто нужны не все элементы, а только подходящие. Например, только чётные числа от 0 до 9:
evens = [number for number in range(10) if number % 2 == 0]
print(evens)
# [0, 2, 4, 6, 8]Проверка: в списке пять чисел, все чётные. Условие if ставится в конце: элемент попадает в список, только если условие истинно.
Оператор % — остаток от деления. number % 2 == 0 истинно для чётных чисел.
Условие внутри выражения — это другое
Не путайте фильтр в конце с тернарным выражением в начале. Фильтр решает, брать элемент или нет. Тернарное выражение решает, что именно положить, но берёт все элементы:
# Заменяем нечётные на строку 'odd', чётные оставляем числом
labels = ['odd' if number % 2 else number for number in range(5)]
print(labels)
# ['odd', 'odd', 2, 'odd', 4]Здесь if ... else стоит до for — это часть выражения, а не фильтр. Обратите внимание: элементов пять, ни один не выброшен.
Правило простое:ifбезelseв конце — это фильтр.if ... elseпередfor— это выбор значения. Их легко перепутать, и тогда Python выдаст ошибку синтаксиса.
Шаг 3. Работайте со строками и словарями
Итерировать можно не только числа. Например, привести список слов к верхнему регистру:
words = ['django', 'flask', 'fastapi']
upper = [word.upper() for word in words]
print(upper)
# ['DJANGO', 'FLASK', 'FASTAPI']Или отфильтровать слова длиннее четырёх букв:
words = ['django', 'flask', 'orm', 'api']
long_words = [word for word in words if len(word) > 4]
print(long_words)
# ['django', 'flask']Проверка: в long_words два элемента — 'django' и 'flask'. Короткие 'orm' и 'api' отсеялись.
Родственники: множества и словари
Тот же синтаксис работает не только для списков. Заменив квадратные скобки на фигурные, вы получаете включение для множества или словаря:
| Что нужно | Скобки | Пример |
|---|---|---|
| Список (list) | [ ] | [x*2 for x in range(3)] |
| Множество (set) | { } | {x*2 for x in range(3)} |
| Словарь (dict) | { : } | {x: x*2 for x in range(3)} |
Множество автоматически убирает дубликаты, а словарь требует пару ключ: значение. Начните с обычных списков — остальное освоите потом.
Если не получилось
Три ошибки, на которые чаще всего натыкаются новички:
SyntaxError: invalid syntax— скорее всего, вы поставилиif ... elseв конце строки. Тернарное выражение должно стоять доfor, а простой фильтр — после. Проверьте порядок частей.NameError: name 'number' is not defined— вы используете в выражении переменную, которой нет вfor-части. Имя послеforи имя в начале выражения должны совпадать.- Результат — пустой список
[]— условие-фильтр отсеяло всё. Уберитеifи посмотрите, что вообще попадает в список, потом настраивайте условие.
Когда включение лучше не писать
Списковое включение хорошо для простых преобразований. Как только внутри появляется двойная вложенность, длинное условие или побочный эффект (запись в файл, вызов print), читаемость падает. Обычный цикл с телом на несколько строк понятнее одной длинной строки, которую приходится расшифровывать.
# Так делать не стоит — нечитаемо
result = [transform(x) for row in matrix for x in row if x > 0 and x < 100]
# Понятнее обычным циклом, если логика растётЧто делать дальше
Когда простые включения станут привычными, посмотрите на генераторные выражения — они пишутся так же, но в круглых скобках, и не создают список в памяти целиком. Это важно для больших объёмов данных: sum(x*x for x in range(1000000)) не займёт лишней памяти под промежуточный список. Дальше — вложенные включения и dict-включения для группировки данных. Но их берите, только когда однострочник действительно читается лучше цикла.
Источники: Python docs — List Comprehensions (tutorial), Python Language Reference — Displays for lists, sets and dictionaries
Частые вопросы
А если у меня Python 2 — сработает?
Списковое включение всегда быстрее обычного цикла?
Можно ли вкладывать одно включение в другое?
Чем генераторное выражение отличается от спискового включения?
Не сработало, вместо списка выводится что-то вроде generator object — почему?
Как отфильтровать элементы и одновременно их преобразовать?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.