Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Списковые генераторы в Python
Списковые генераторы (list comprehensions) — это компактный и эффективный способ создания списков. Это один из самых мощных инструментов Python.
1. Базовый синтаксис
# Обычный способ
squares = []
for x in range(10):
squares.append(x ** 2)
# Списковый генератор
squares = [x ** 2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Синтаксис
[выражение for переменная in последовательность]
2. Условие в генераторе
# Только чётные числа
evens = [x for x in range(10) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8]
# Только квадраты чисел > 20
big_squares = [x ** 2 for x in range(10) if x ** 2 > 20]
print(big_squares) # [25, 36, 49, 64, 81]
# Условное выражение (ternary operator)
result = ["even" if x % 2 == 0 else "odd" for x in range(5)]
print(result) # ['even', 'odd', 'even', 'odd', 'even']
3. Вложенные циклы
# Создать матрицу 3x3
matrix = [[i * 3 + j for j in range(3)] for i in range(3)]
print(matrix)
# [[0, 1, 2],
# [3, 4, 5],
# [6, 7, 8]]
# Развернуть матрицу в список
flat = [x for row in matrix for x in row]
print(flat) # [0, 1, 2, 3, 4, 5, 6, 7, 8]
# Декартово произведение
pairs = [(x, y) for x in [1, 2] for y in [3, 4]]
print(pairs) # [(1, 3), (1, 4), (2, 3), (2, 4)]
4. Работа со строками
# Преобразовать строку в список букв
letters = [c.upper() for c in "hello"]
print(letters) # ['H', 'E', 'L', 'L', 'O']
# Разбить слова на буквы
words = "hello world".split()
letters = [letter for word in words for letter in word]
print(letters) # ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']
# Фильтровать слова
words = ["hello", "world", "hi", "python"]
long_words = [w for w in words if len(w) > 3]
print(long_words) # ['hello', 'world', 'python']
5. Set comprehension (генератор множеств)
# Создать множество
unique_squares = {x ** 2 for x in [1, 2, 2, 3, 3, 3]}
print(unique_squares) # {1, 4, 9}
# Фильтрация
even_squares = {x ** 2 for x in range(10) if x % 2 == 0}
print(even_squares) # {0, 4, 16, 36, 64}
6. Dictionary comprehension (генератор словарей)
# Создать словарь {число: квадрат}
squares_dict = {x: x ** 2 for x in range(5)}
print(squares_dict) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
# С условием
even_squares_dict = {x: x ** 2 for x in range(10) if x % 2 == 0}
print(even_squares_dict) # {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}
# Инвертировать словарь
original = {"a": 1, "b": 2, "c": 3}
inverted = {v: k for k, v in original.items()}
print(inverted) # {1: 'a', 2: 'b', 3: 'c'}
# Превратить список в словарь
names = ["Alice", "Bob", "Charlie"]
name_lengths = {name: len(name) for name in names}
print(name_lengths) # {'Alice': 5, 'Bob': 3, 'Charlie': 7}
7. Generator expression (выражение-генератор)
Это как список, но вычисляет значения по мере необходимости (экономит память):
# Список — всё в памяти
squares_list = [x ** 2 for x in range(1000000)]
print(sys.getsizeof(squares_list)) # ~8 MB
# Генератор — лениво вычисляет
squares_gen = (x ** 2 for x in range(1000000))
print(sys.getsizeof(squares_gen)) # ~128 bytes
# Использовать генератор
for square in squares_gen:
print(square) # Вычисляется на лету
# Генератор можно использовать только один раз
sum(squares_gen) # Потребляет генератор
list(squares_gen) # Пусто — генератор уже исчерпан
8. Сложные примеры
Фильтрация и трансформация данных
students = [
{"name": "Alice", "grade": 95},
{"name": "Bob", "grade": 75},
{"name": "Charlie", "grade": 88},
]
# Получить имена отличников
failed = [s["name"] for s in students if s["grade"] >= 90]
print(failed) # ['Alice']
# Преобразовать в другой формат
report = [f"{s['name']}: {s['grade']}%" for s in students]
print(report) # ['Alice: 95%', 'Bob: 75%', 'Charlie: 88%']
Вложенные структуры данных
# Группировка
data = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
result = [x * 2 for row in data for x in row]
print(result) # [2, 4, 6, 8, 10, 12, 14, 16, 18]
# Фильтрация вложенных данных
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
even_elements = [x for row in matrix for x in row if x % 2 == 0]
print(even_elements) # [2, 4, 6, 8]
Обработка файлов
# Прочитать файл и обработать строки
lines = [line.strip().upper() for line in open('file.txt') if line.strip()]
# Или с контекстным менеджером
with open('file.txt') as f:
lines = [line.strip().upper() for line in f if line.strip()]
print(lines)
9. Производительность
import timeit
# Список
def traditional():
result = []
for x in range(1000):
if x % 2 == 0:
result.append(x ** 2)
return result
# Генератор списка
def comprehension():
return [x ** 2 for x in range(1000) if x % 2 == 0]
# Генератор
def generator():
return (x ** 2 for x in range(1000) if x % 2 == 0)
print("Traditional:", timeit.timeit(traditional, number=10000))
print("Comprehension:", timeit.timeit(comprehension, number=10000))
print("Generator:", timeit.timeit(generator, number=10000))
# Результат (примерный):
# Traditional: 4.2s
# Comprehension: 2.1s (в 2x быстрее!)
# Generator: 1.8s
Генератор списков быстрее традиционного цикла!
10. Когда ИЗБЕГАТЬ списковых генераторов
1. Сложные вложенные генераторы
# ❌ Нечитаемо
result = [[y * 2 for y in x if y % 2 == 0] for x in data if x]
# ✅ Лучше
result = []
for row in data:
if row:
filtered = [y * 2 for y in row if y % 2 == 0]
result.append(filtered)
2. Побочные эффекты
# ❌ Генератор не для этого
result = [print(x) for x in range(5)] # Печатает и возвращает None
# ✅ Используй цикл
for x in range(5):
print(x)
3. Очень большие последовательности
# ❌ Съедает всю память
big_list = [x for x in range(1_000_000_000)]
# ✅ Используй генератор
big_gen = (x for x in range(1_000_000_000))
for x in big_gen:
process(x)
Практические применения
# 1. Валидация данных
emails = [e for e in email_list if "@" in e and "." in e]
# 2. Преобразование типов
numbers = [int(x) for x in string_list]
# 3. Извлечение полей из объектов
names = [user.name for user in users if user.active]
# 4. Дублирование элементов
duplicated = [x for x in numbers for _ in range(2)]
# [1, 2, 2, 3, 3, 4, 4] из [1, 2, 3, 4]
# 5. Комбинирование списков
result = [x + y for x in list1 for y in list2]
Выводы
- Списковые генераторы — компактнее и быстрее чем циклы
- Генератор-выражения — экономят память для больших последовательностей
- Dict/Set comprehension — для создания словарей и множеств
- Избегайте сложных вложенных структур (нечитаемо)
- Побочные эффекты — используй циклы, не генераторы
- Производительность — в 2x быстрее чем традиционные циклы