#2 Генераторы могут получать значения с помощью метода send()
.
Объединение генераторов
Объедините несколько генераторов для создания единого потока данных. Этот трюк позволяет обрабатывать данные в несколько этапов без создания промежуточных списков.
def first_ten_numbers(): for i in range(10): yield i def square_numbers(numbers): for num in numbers: yield num * num squared = square_numbers(first_ten_numbers()) print(list(squared)) # Output: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Использование send()
Генераторы могут получать значения с помощью метода send()
. Этот трюк позволяет динамически контролировать поведение генератора.
def repeater(): value = None while True: received = yield value if received is not None: value = received rep = repeater() next(rep) print(rep.send("Hello")) # Output: Hello print(rep.send("World")) # Output: World
Генераторы с itertools
Модуль itertools
содержит функции, возвращающие итераторы. Объедините их с генераторами для получения мощных результатов.
import itertools def limited_cycle(iterable, limit): infinite = itertools.cycle(iterable) for _ in range(limit): yield next(infinite) print(list(limited_cycle("AB", 5))) # Output: ['A', 'B', 'A', 'B', 'A']
Сопрограммы на основе генераторов
Сопрограммы — это генераторы, которые могут потреблять и создавать значения. Они идеально подходят для создания конвейеров данных.
def grep(pattern): print(f"Looking for {pattern}") while True: line = (yield) if pattern in line: print(line) search = grep("Python") next(search) search.send("I love Python!")
Бесконечные генераторы
Генераторы могут создавать бесконечные последовательности. Используйте их с умом, чтобы избежать бесконечных циклов.
def infinite_ones(): while True: yield 1 # Use islice to get a finite sequence from an infinite generator finite_ones = itertools.islice(infinite_ones(), 5) print(list(finite_ones)) # Output: [1, 1, 1, 1, 1]