One salient feature of iterators is that they may be used only once. In order to use the iterator again, you will have to create a new iterator object. Note that an iterable object is able to create new iterators as many times as necessary. Let's examine the case of a list:
L = ['a', 'b', 'c'] iterator = iter(L) list(iterator) # ['a', 'b', 'c'] list(iterator) # [] empty list, because the iterator is exhausted
new_iterator = iter(L) # new iterator, ready to be used list(new_iterator) # ['a', 'b', 'c']
Each time a generator object is called, it creates a new iterator. Hence, when that iterator is exhausted, you have to call the generator again to obtain a new iterator:
g = odd_numbers(10) for k in g: ... # do something with k # now the iterator is exhausted: for k in g: # nothing will happen!! ... # to loop through it again, create a new one:...