I'd like to yield random values from a generator, and I want to be able to yield them an indefinite number of times, so I wrap the generator in itertools.cycle
.
Below is a sample implementation.
from itertools import cycle
import numpy as np
def generator(batch_size):
for _ in range(batch_size):
yield np.random.randint(0,50)
np.random.seed(111)
batch_size = 3
gen = cycle(generator(batch_size))
for _ in range(10):
print([next(gen) for _ in range(batch_size)])
And the output:
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
[20, 44, 20]
Notice the output just repeats the same three numbers.
My intuition was that the generator should be "re-started" at the beginning of each cycle, but it appears that's not the case. Instead, it appears that the generator is run once to yield the initial list, and then the output is repeated indefinitely.
An alternative strategy to achieve the desired behavior is to discard the cycle
and instead pass an infinite=True
parameter to the generator, then use a while True
loop instead of a for _ in range(...)
loop:
def generator(batch_size, infinite):
while True:
for _ in range(batch_size):
yield np.random.randint(0,50)
if not infinite:
break
But that feels clumsy.
Is there any construct that I can use to wrap the generator so that it is actually re-started for every cycle?