Ответ 1
Есть много отличных ответов на генераторы, поэтому я не буду подробно останавливаться на этом.
Генераторы сохраняют состояние. Они немного медленнее, если вы выполняете очень быстрые операции (например, используя sum
, но если вы используете команду ввода-вывода, то не будет большой разницы). Потенциал роста генераторов заключается в том, что они не загружают все элементы в память заранее, когда списки выполняются.
Это то, что происходит, когда вы перебираете список (на очень высоком уровне):
- Вы загружаете все элементы списка в память
- Запрос следующего элемента просто дает вам указатель на этот объект
Сравните это с генератором:
- У вас нет всех предметов в памяти. Только по одному пункту за раз.
- Запрос следующего элемента возобновляет объект-генератор, запустив код, пока он не достигнет инструкции yield.
- Затем он возвращает адрес объекта в памяти, чтобы вы могли получить к нему доступ.
Этот дополнительный шаг посередине - это разница в ваших тестах.
Таким образом, генераторы обычно используются там, где вы имеете дело с огромным объемом данных, которые необходимо загрузить в память. (Существует больше случаев использования генераторов, например, сопрограмм)
Выполняйте истечение с огромными файлами и цикл для печати строк. В какой-то момент вы получите исключение из памяти при использовании списков. Затем попробуйте использовать генераторы, они не исчезнут из памяти.