List comprehensions
List comprehensions
До этого, чтобы создать список по формуле, мы использовали цикл for с append. Python предлагает более компактную и Pythonic-идиому: list comprehension — генератор списка. Это один из тех приёмов, которые делают Python-код элегантным.
Проблема: цикл + append
Классический способ создать список квадратов:
squares = []
for x in range(1, 6):
squares.append(x ** 2)
print(squares) # [1, 4, 9, 16, 25]
Это работает, но требует трёх строк для простой операции.
List comprehension: синтаксис
[выражение for переменная in итерируемое]
Тот же список квадратов в одну строку:
squares = [x ** 2 for x in range(1, 6)]
print(squares) # [1, 4, 9, 16, 25]
Читается как: «создать список, где каждый элемент — это x ** 2 для x в range(1, 6)».
Больше примеров
# Удвоенные числа:
doubled = [n * 2 for n in range(1, 6)]
print(doubled) # [2, 4, 6, 8, 10]
# Длины строк:
words = ["apple", "banana", "cherry", "kiwi"]
lengths = [len(w) for w in words]
print(lengths) # [5, 6, 6, 4]
# Все буквы в верхнем регистре:
upper = [w.upper() for w in words]
print(upper) # ['APPLE', 'BANANA', 'CHERRY', 'KIWI']
# Квадраты как строки:
str_sq = [str(x ** 2) for x in range(1, 6)]
print(str_sq) # ['1', '4', '9', '16', '25']
Фильтрация: условие if
List comprehension поддерживает фильтрацию через необязательный if в конце:
[выражение for переменная in итерируемое if условие]
# Только чётные числа:
evens = [x for x in range(1, 11) if x % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
# Слова длиной больше 4 символов:
words = ["apple", "pie", "banana", "fig", "cherry"]
long_words = [w for w in words if len(w) > 4]
print(long_words) # ['apple', 'banana', 'cherry']
# Положительные числа из смешанного списка:
mixed = [-3, 0, 5, -1, 7, -9, 2]
positives = [x for x in mixed if x > 0]
print(positives) # [5, 7, 2]
Трансформация + фильтрация вместе
Можно и трансформировать, и фильтровать одновременно:
# Квадраты нечётных чисел от 1 до 10:
odd_squares = [x ** 2 for x in range(1, 11) if x % 2 != 0]
print(odd_squares) # [1, 9, 25, 49, 81]
List comprehension с несколькими for
Можно вкладывать несколько for для создания комбинаций:
# Все пары (i, j):
pairs = [(i, j) for i in range(1, 4) for j in range(1, 4)]
print(pairs)
# [(1,1),(1,2),(1,3),(2,1),(2,2),(2,3),(3,1),(3,2),(3,3)]
Это эквивалентно вложенным циклам, но записано компактнее.
Когда list comprehension, а когда for
List comprehension уместен, когда:
- Логика простая: одна формула, один
if. - Результат — список.
- Код помещается в одну строку и читается легко.
Обычный for предпочтителен, когда:
- Нужно выполнить несколько действий на каждой итерации.
- Логика сложная — лучше разнести по строкам.
- Нужно аккумулировать что-то, кроме списка.
# Не надо: слишком сложный comprehension
result = [x if x > 0 else -x for x in range(-5, 6) if x != 0]
# Лучше как обычный цикл с комментарием
result = []
for x in range(-5, 6):
if x != 0:
result.append(abs(x))
Производительность
List comprehension обычно быстрее эквивалентного for + append, потому что оптимизирован интерпретатором. Но для больших данных разница незначительна — выбирайте по читаемости.
Проверь себя
Что делает следующий comprehension?
result = [x * 2 for x in range(1, 6) if x % 2 != 0]
Диапазон 1..5, нечётные (x % 2 != 0): 1, 3, 5. Умноженные на 2: 2, 6, 10. Результат: [2, 6, 10].
Итог
- List comprehension:
[выражение for var in iterable]— компактный способ создать список. - С фильтром:
[выражение for var in iterable if условие]. - С несколькими
for: создание комбинаций. - Читаем как «создай список из
выражениедля каждогоvarвiterable». - Предпочтительны для простой однострочной логики; сложные случаи — обычный цикл.
Модуль 5 завершён! Вы освоили списки (создание, методы, сортировка, поиск) и кортежи (неизменяемость, распаковка). В следующем модуле переходим к словарям и множествам.