Python Lab

List comprehension в Python: от простого к сложному

Как писать list, dict и set comprehension. Вложенные включения, условия, генераторные выражения.

20 ноября 2025 г.·8 мин чтения
list comprehensionгенераторыpython basics

Что такое list comprehension?

List comprehension — компактный способ создать список из другой последовательности:

squares = [x ** 2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Эквивалент через цикл:

squares = []
for x in range(10):
    squares.append(x ** 2)

Comprehension короче, читается слева направо и обычно быстрее.


Базовый синтаксис

[выражение for переменная in итерируемое]
names = ["alice", "bob", "carol"]
upper = [name.upper() for name in names]
# ['ALICE', 'BOB', 'CAROL']

С фильтрацией (if)

[выражение for переменная in итерируемое if условие]
numbers = range(20)
evens = [n for n in numbers if n % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]

If-else в выражении

Тернарный оператор стоит до for:

result = ["чётное" if n % 2 == 0 else "нечётное" for n in range(5)]
# ['чётное', 'нечётное', 'чётное', 'нечётное', 'чётное']

Вложенные comprehension

Для работы с матрицами или вложенными списками:

matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

# Транспонирование
transposed = [[row[i] for row in matrix] for i in range(3)]
# [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

# Плоский список (flatten)
flat = [item for row in matrix for item in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Dict comprehension

words = ["apple", "banana", "cherry"]
lengths = {word: len(word) for word in words}
# {'apple': 5, 'banana': 6, 'cherry': 6}

Инвертирование словаря:

original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}

Set comprehension

sentence = "привет мир привет python"
unique_words = {word for word in sentence.split()}
# {'привет', 'мир', 'python'}

Генераторные выражения

Синтаксис как у list comprehension, но в скобках (). Не создаёт список сразу — вычисляет элементы по одному:

gen = (x ** 2 for x in range(1_000_000))
print(next(gen))   # 0
print(next(gen))   # 1

Экономят память при работе с большими данными:

# Сумма квадратов без создания промежуточного списка
total = sum(x ** 2 for x in range(1_000_000))

Когда использовать comprehension, а когда цикл

Comprehension — когда:

  • Создаёте новый список/словарь/множество
  • Логика простая, умещается в одну строку
  • Нужна фильтрация

Цикл — когда:

  • Побочные эффекты (print, запись в файл)
  • Сложная многошаговая логика
  • Нужен break/continue
# ❌ Плохо — comprehension для побочного эффекта
[print(x) for x in range(10)]

# ✅ Хорошо — цикл для побочного эффекта
for x in range(10):
    print(x)

Производительность

List comprehension обычно быстрее явного цикла с append():

import timeit

# Цикл: ~0.5 сек
timeit.timeit("r = []\nfor x in range(1000): r.append(x**2)", number=10000)

# Comprehension: ~0.3 сек
timeit.timeit("[x**2 for x in range(1000)]", number=10000)

Практические паттерны

Фильтрация None

data = [1, None, 3, None, 5]
clean = [x for x in data if x is not None]
# [1, 3, 5]

Уникальные элементы с сохранением порядка

seen = set()
unique = [x for x in [3, 1, 2, 1, 3, 4] if not (x in seen or seen.add(x))]
# [3, 1, 2, 4]

Разбивка на части (chunks)

lst = list(range(10))
chunks = [lst[i:i+3] for i in range(0, len(lst), 3)]
# [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]

Декартово произведение

colors = ["red", "green"]
sizes = ["S", "M", "L"]
variants = [(c, s) for c in colors for s in sizes]
# [('red', 'S'), ('red', 'M'), ('red', 'L'), ('green', 'S'), ...]

Итог

ТипСинтаксисРезультат
List[expr for x in it]list
Dict{k: v for x in it}dict
Set{expr for x in it}set
Generator(expr for x in it)generator

Comprehension — один из самых питоничных инструментов Python. Практикуйте их в задачах тренажёра!

Хочешь закрепить знания?

Попробуй решить задачи на Python в интерактивном тренажёре

К задачам