Бесконечные последовательности

Генераторы могут использоваться для представления бесконечных последовательностей:

 def integers_starting_from(n):
    while True:
        yield n
        n += 1

natural_numbers = integers_starting_from(1)

 

Бесконечная последовательность чисел , как описано выше , также может быть получена с помощью itertools.count . Код выше может быть написан как ниже

 natural_numbers = itertools.count(1)



 

Вы можете использовать генераторы на бесконечных генераторах для создания новых генераторов:

 multiples_of_two = (x * 2 for x in natural_numbers)
multiples_of_three = (x for x in natural_numbers if x % 3 == 0)

 

Имейте в виду , что бесконечный генератор не имеет конца, поэтому передавая его в любой функции , которая будет пытаться потреблять генератор полностью будет иметь пагубные последствия:

 list(multiples_of_two)  # will never terminate, or raise an OS-specific error

 

Вместо этого, список с помощью кнопок / установите постижения с range (или xrange для Python <3.0):

 first_five_multiples_of_three = [next(multiples_of_three) for _ in range(5)] 
# [3, 6, 9, 12, 15]

 

или использовать itertools.islice() , чтобы нарезать итератор к подмножеству:

 from itertools import islice
multiples_of_four = (x * 4 for x in integers_starting_from(1))
first_five_multiples_of_four = list(islice(multiples_of_four, 5))
# [4, 8, 12, 16, 20]

 

Обратите внимание, что оригинальный генератор также обновляется, как и все другие генераторы, исходящие из того же «корня»:

 next(natural_numbers)    # yields 16
next(multiples_of_two)   # yields 34
next(multiples_of_four)  # yields 24

 

Бесконечная последовательность также может повторяться с for -loop . Убедитесь в том , чтобы включить условный break оператор так , что цикл будет завершить в конце концов:

 for idx, number in enumerate(multiplies_of_two):
    print(number)
    if idx == 9:
        break  # stop after taking the first 10 multiplies of two

 

Классический пример - числа Фибоначчи

 import itertools

def fibonacci():
    a, b = 1, 1
    while True:
        yield a
        a, b = b, a + b

first_ten_fibs = list(itertools.islice(fibonacci(), 10))
# [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]

def nth_fib(n):
    return next(itertools.islice(fibonacci(), n - 1, n))

ninety_nineth_fib = nth_fib(99)  # 354224848179261915075