There is no way to generate a reset generator. However, you can use itertools.tee to βcopyβ the iterator.
>>> z = zip(a, b) >>> zip1, zip2 = itertools.tee(z) >>> list(zip1) [(1, 7), (2, 8), (3, 9)] >>> list(zip2) [(1, 7), (2, 8), (3, 9)]
This includes caching values, so it makes sense only if you repeat both iterators at about the same speed. (In other words, do not use it like I am here!)
Another approach is to pass the function of the generator and call it whenever you want to iterate over it.
def gen(x): for i in range(x): yield i ** 2 def make_two_lists(gen): return list(gen()), list(gen())
But now you have to bind the arguments to the generator function when passing it. You can use lambda for this, but many people find lambda ugly. (Not me, though! YMMV.)
>>> make_two_lists(lambda: gen(10)) ([0, 1, 4, 9, 16, 25, 36, 49, 64, 81], [0, 1, 4, 9, 16, 25, 36, 49, 64, 81])
I hope it goes without saying that in most cases it is best to compile a list and copy it.
Also, as a more general way of explaining this behavior, consider this. The generator point should produce a series of values, while maintaining some state between iterations. Now, sometimes, instead of just sorting through the generator, you can do something like this:
z = zip(a, b) while some_condition(): fst = next(z, None) snd = next(z, None) do_some_things(fst, snd) if fst is None and snd is None: do_some_other_things()
Say this cycle may or may not exhaust z . Now we have the generator in uncertain condition! Therefore, at the moment it is important that the behavior of the generator is restrained in a clearly defined way. Although we do not know where the generator is located, we know that a) all subsequent calls will give later values ββin the series, and b) after it is βemptyβ, we received all the elements in the sequence exactly once. The more we have to manipulate the z state, the more difficult it is to reason about it, therefore it is better to avoid situations that violate these two promises.
Of course, as Joel Cornett points out, below you can write a generator that receives messages through the send method; and one could write a generator that could be reset using send . But note that in this case, all we can do is send a message. We cannot directly manipulate the state of the generator, and therefore, all changes in the state of the generator are clearly defined (by the generator itself, provided that it is written correctly!). send really intended for implementing coroutines , so I would not use it for this purpose. Every day, generators almost never do anything with the values ββsent to them - I think for the reasons I cited above.