Выбор ответа Junior Итераторы и генераторы спрашивают часто обновлено
Генераторное выражение против list comprehension
Вопрос
Почему sum(x * x for x in range(10**8)) использует почти константную память, а sum([x * x for x in range(10**8)]) нет?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Генератор отдаёт элементы по одному, а comprehension строит список. Круглые скобки дают ленивый генератор: следующий квадрат вычисляется, когда sum его запрашивает, и сразу выбрасывается.
Варианты ответа
- Генераторное выражение кеширует результат в файле на диске
- Генератор отдаёт элементы по одному, а comprehension строит списокправильный ответ
sumпо-разному оптимизирован для списков и генераторов, а память одинаковая- Квадратные скобки создают кортеж, который хранит лишние ссылки
Разбор
Круглые скобки дают ленивый генератор: следующий квадрат вычисляется, когда sum его запрашивает, и сразу выбрасывается. Квадратные скобки создают список из 10⁸ чисел целиком. Диск тут ни при чём, кортеж создаётся через tuple(...), а не квадратными скобками. По скорости список иногда чуть быстрее, но память несравнима.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Термины по теме
Ещё по теме «Итераторы и генераторы»
- Когда выполняется тело генератора
- Разбить последовательность на пачки
- Рекурсивно развернуть вложенные списки
- Конвейер обработки лога на генераторах
- Свой итерируемый класс, который можно обходить много раз
- Когда выполняется finally в недочитанном генераторе
- Полезные функции itertools
- Ленивые вычисления