Эти две конструкции представляют разные подходы к обработке последовательностей в Python:
numbers = [x**2 for x in range(5)] # [0, 1, 4, 9, 16]
print(numbers[2]) # 4 (доступ по индексу)
squares = (x**2 for x in range(5)) # generator object
print(next(squares)) # 0 (только последовательный доступ)
print(next(squares)) # 1
Характеристика | List Comprehension | Generator Expression |
---|---|---|
Тип результата | Список (list) | Генератор (generator) |
Вычисление | Сразу (eager) | По требованию (lazy) |
Память | Хранит все элементы | Хранит только текущий |
Повторное использование | Да | Нет (одноразовый) |
Скорость доступа | Быстрый произвольный доступ | Только последовательный |
Синтаксис | Квадратные скобки [] | Круглые скобки () |
# Пример хорошего использования
names = [user.name for user in users if user.active]
names.sort() # Можно сортировать
print(names[0]) # Доступ по индексу
# Пример хорошего использования
total = sum(x**2 for x in range(1000000)) # Не храним список в памяти
processed = (transform(x) for x in data_stream) # Обработка потока
import sys
# List Comprehension
list_comp = [x for x in range(1000000)]
print(sys.getsizeof(list_comp)) # 8448728 байт (8.4 MB)
# Generator Expression
gen_exp = (x for x in range(1000000))
print(sys.getsizeof(gen_exp)) # 112 байт
Генераторные выражения в функциях — круглые скобки можно опускать:
sum(x**2 for x in range(10)) # Корректный синтаксис
Преобразование в список:
gen_to_list = list(x for x in range(5)) # [0, 1, 2, 3, 4]
Цепочки обработки:
pipeline = (transform(x) for x in data if x is not None)
Основное отличие: [x for x in y]
сразу создает список в памяти, а (x for x in y)
возвращает генератор для ленивых вычислений. Выбор зависит от требований к памяти, способу доступа к данным и необходимости повторного использования. List comprehension подходит для работы с небольшими наборами данных, требующих многократного доступа, тогда как generator expression оптимален для обработки больших или потоковых данных.