Генератор – это итератор, элементы которого можно итерировать только 1 раз

Выражение генаратор (Generator Expressions)

Выглядят также как генераторы списка, только не в [] а в ()

my_generator = (i for i in range(10))

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

def generator():
    for i in range(2):
        yield i

# Пример работы 1 
a = generator()
print(next(a)) # 0
print(next(a)) # 1
print(next(a)) # StopIteration

# Пример работы 2
a = generator()

for i in a:
    print(i)
# 1
# 2
def fibon(n):
    a = b = 1
    for i in range(n):
        yield a
        a, b = b, a + b

for x in fibon(10):
    print(x)

В объекте генераторе определены методы iter и next, то есть реализован протокол итератора, то есть по сути любой генератор является итератором. Концептуально, итератор — это механизм поэлементного обхода данных, а генератор позволяет отложено создавать результат при итерации.

Генератор может создавать результат на основе какого то алгоритма или брать элементы из источника данных(коллекция, файлы, сетевое подключения и пр) и изменять их.

Ярким пример являются функции range и enumerate:

*range* генерирует ограниченную арифметическую прогрессию целых чисел, не используя никакой источник данных.

*enumerate* генерирует двухэлементные кортежи с индексом и одним элементом из итерируемого объекта.