Генераторы это итерируемые объекты, но не сохраняющие значения в память, а генерирующие новое значение при попытке получить следующий элемент (По генератору можно пройти циклом только 1 раз и нет доступа к индексам) когда в функции появляется yield
она, останавливает выполнение и передаёт объект в цикл.
К примеру при запуске этого кода:
def find_word(file, word):
g_indx = 0 # Индекс начала строки в файле
for line in file: # Идём по каждой линии
indx = 0 # Индекс слова в строке
while (indx != -1): # Пока есть слово
indx = line.find(word, indx) # Находим следующие слово
if indx > -1: # Если слово было найдено
print('Found!') # Добавил для наглядности
yield g_indx + indx # Возвращаем индекс от начала файла
# Прибавляем к строчному индексу 1
# Чтобы это слово не находилось find
indx += 1
# Добавляем к индексу начала строки её длину
g_indx += len(line)
for index in find_word("строка 1\n2. строка 2\nТретья строка".splitlines(), "строка"):
print(index)
Результат будет следующим:
Found! # Функция выполняется пока не найдёт слово
0 # После передаёт в цикл
Found! # И когда тело цикла отработало продолжает свою работу
11
Found!
26
Следующее значение генератора также можно получить с помощью функции next(iter)