Получить доступ

Чем list comprehension отличается от генераторного выражения?

JuniorИтераторы и генераторы
Ещё спрашивают так:
  • В чём разница между [x for x in a] и (x for x in a)?
  • Когда использовать генераторное выражение?
Коротко

[...] сразу строит весь список в памяти, (...) — ленивый генератор.

  • Список: нужен повторный проход, индексы, len
  • Генератор: результат проходится один раз, особенно в sum, any, max

А ещё sum(x * x for x in data) — скобки генератора можно опустить, если он единственный аргумент

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Синтаксис почти одинаковый, разница в результате:

  • list comprehension [f(x) for x in data if cond] выполняется сразу и возвращает готовый список. Память — O(n). Список можно обходить много раз, брать по индексу, узнавать длину;
  • генераторное выражение (f(x) for x in data if cond) ничего не считает при создании. Оно отдаёт значения по одному при обходе. Память — O(1), но пройти его можно один раз.

Когда генератор лучше: данные большие или бесконечные, результат сразу сворачивается (sum, min, any, "".join), или нужен только первый подходящий элемент — any и next остановятся на нём.

Когда список лучше: результат нужен несколько раз, нужен len или индекс, или данных мало — тогда список даже немного быстрее.

Ещё есть dict и set comprehension: {k: v for ...}, {x for ...}. Отдельного «tuple comprehension» нет: (x for x in a) — это генератор, а кортеж получают через tuple(x for x in a).

Пример

data = range(10_000_000)

squares = [x * x for x in data]     # ~ сотни МБ в памяти
total = sum(x * x for x in data)    # память почти не растёт

has_negative = any(x < 0 for x in data)   # остановится на первом найденном

gen = (x for x in range(3))
list(gen)    # [0, 1, 2]
list(gen)    # [] — уже исчерпан

Что хотят услышать

  • Жадное вычисление против ленивого.
  • Память O(n) против O(1).
  • Когда что выбирать, на примерах sum/any.
  • Одноразовость генератора.

Частые ошибки

  • Думать, что круглые скобки дают кортеж.
  • Использовать генератор, а потом пытаться пройти его второй раз.

Что спросят дальше

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем