Подтвердить что ты не робот

Генераторы и петли в Python

Итак, у меня есть функция-генератор, которая выглядит так.

def generator():
    while True:
        for x in range(3):
            for j in range(5):
                yield x

После загрузки этой функции и вызова "next" несколько раз, я ожидаю, что она даст значения

0 0 0 0 0 1 1 1 1 1 2 2 2 2 2 0 0 0 0 0 ...

Но вместо этого он просто дает 0 все время. Почему это?

>>> execfile("test.py")
>>> generator
<function generator at 0x10b6121b8>
>>> generator().next()
0
>>> generator().next()
0
>>> generator().next()
0
>>> generator().next()
0
>>> generator().next()
0
>>> generator().next()
0
>>> generator().next()
0
4b9b3361

Ответ 1

generator() инициализирует новый объект генератора:

In [4]: generator() is generator() # Creating 2 separate objects
Out[4]: False

Затем generator().next() получает первое значение от вновь созданного объекта генератора (0 в вашем случае).

Вызов generator один раз:

In [5]: gen = generator() # Storing new generator object, will reuse it

In [6]: [gen.next() for _ in range(6)] # Get first 6 values for demonstration purposes
Out[6]: [0, 0, 0, 0, 0, 1]

Примечание: generator.next был удален из Python 3 (PEP 3114) - используйте next функцию вместо:

In [7]: next(gen)
Out[7]: 1

Ответ 2

При каждом вызове generator вы создаете новый объект-генератор:

generator().next() # 1st item in 1st generator 
generator().next() # 1st item in 2nd generator

Создайте один генератор, а затем вызовите next для следующих элементов:

g = generator()

g.next() # 1st item in 1st generator
g.next() # 2nd item in 1st generator

Ответ 3

Я разместил его в комментарии, я думаю, если вы посмотрите на это параллельно с вопросом, вы видите ошибку:

with open('my_file.txt', 'r') as f: 
    print(f.readline())               # `readline` simply reads a single line

with open('my_file.txt', 'r') as f: 
    print(f.readline())

with open('my_file.txt', 'r') as f: 
    print(f.readline())

with open('my_file.txt', 'r') as f: 
    print(f.readline())    

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

mygen = generator()
mygen.next()
mygen.next()
...
etc