Выбор ответа Junior Итераторы и генераторы спрашивают часто обновлено

Генераторное выражение против list comprehension

Вопрос

Почему sum(x * x for x in range(10**8)) использует почти константную память, а sum([x * x for x in range(10**8)]) нет?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Генератор отдаёт элементы по одному, а comprehension строит список. Круглые скобки дают ленивый генератор: следующий квадрат вычисляется, когда sum его запрашивает, и сразу выбрасывается.

Варианты ответа

  1. Генераторное выражение кеширует результат в файле на диске
  2. Генератор отдаёт элементы по одному, а comprehension строит списокправильный ответ
  3. sum по-разному оптимизирован для списков и генераторов, а память одинаковая
  4. Квадратные скобки создают кортеж, который хранит лишние ссылки

Разбор

Круглые скобки дают ленивый генератор: следующий квадрат вычисляется, когда sum его запрашивает, и сразу выбрасывается. Квадратные скобки создают список из 10⁸ чисел целиком. Диск тут ни при чём, кортеж создаётся через tuple(...), а не квадратными скобками. По скорости список иногда чуть быстрее, но память несравнима.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.

Термины по теме