Генераторы в python

В Python генератор - это объект, который предназначен для создания последовательностей. С его помощью вы можете итерировать потенциально огромные последовательности, не создавая и не сохраняя всю последовательность в памяти сразу.
Генераторы часто становятся источником данных для итераторов.

В Python 2 функция range() возвращает список, ограниченный так, чтобы он помещался в память. В Python 2 также есть функция xrange(), которая стала обычной функцией range() в Python 3. В этом примере складываются все целые числа от 1 до 100:

>>> sum(range(1, 101))
5050

Каждый раз при итерации через генератор, он отслеживает, где находился во время последнего вызова, и возвращает следующее значение. Это отличает его от обычной функции, которая не помнит о предыдущих вызовах и всегда начинает работу с первой строки в том же состоянии.

Функции-генераторы

Можно самому написать функцию-генератор, если нужно создать потенциально большую последовательность. Это будет обычная функция, но возвращать значение будет с помощью выражения yield, а не return:

>>> def my_range(first=0, last=10, step=1):
		number = first
		while number < last:
			yield number
			number += step
 
# Это обычная функция:
>>> my_range
<function my_range at 0x10193e268>
 
# Возвращает объект генератора:
>>> ranger = my_range(1, 5)
>>> ranger
<generator object my_range at 0x101a0a168>

Можно проитерировать по этому объекту генератора:

>>> for x in ranger:
		print(x)
 
1
2
3
4

Генератор можно запустить только один раз

Списки, множества, строки и словари существуют в памяти, а генераторы создают свои значения на лету и выдают их по одному с помощью итератора.
Генератор не запоминает значения, поэтому не получится перезапустить его или создать резервную копию.

>>> for try_again in ranger:
 	 print(try_again)
 
>>>  # генератор истощился

Включения генераторов (comprehensions)

Заключается в круглые скобки. Оно похоже на сокращенную функцию-генератор, которая неявно выполняет yield и возвращает объект генератора:

>>> genobj = (pair for pair in zip(['a', 'b'], ['1', '2']))
>>> genobj
<generator object <genexpr> at 0x10308fde0>
>>> for thing in genobj:
		print(thing)
 
('a', '1')
('b', '2')

Функции в python
Соус: Книга “Простой Python Глава 9. “ФункцииГенераторы

python