if you iterate a list twice, the 2nd time has all the data from the beginning. but what if you have a case where the data can be figured out as an iterator and would be too large for memory, but you need to iterate it 2 or more times. an example test case would be range() or an equivalent that yields squares of sequence of ints (0,1,4,9,16,...)
for those who like to see code:
def range2(*a):
for x in range(*a):
yield x*x
return None
yeah, that was absurdly simple.
Here is an example of an iterator but it doesn't sound like this is what your looking for. If it is not, can you be more specific about what your needs are.
class range2 :
def __init__ (self, *numbers) :
self.marker = -1
self.numbers = numbers
def __iter__ (self) :
return self
def __next__ (self) :
self.marker += 1
if self.marker < len (self.numbers) :
return self.numbers [self.marker] * self.numbers [self.marker]
else :
raise StopIteration
for test in range2 (1, 2, 3) :
print (test, end = ' ')
print ()
for test in range2 (4, 5, 6) :
print (test, end = ' ')
print ()
Skaperen Wrote:but what if you have a case where the data can be figured out as an iterator and would be too large for memory, but you need to iterate it 2 or more times
Indeed, the answer is: write a generator. A generator is a compact representation of a potentially large or infinite sequence that can be iterated many times.
yeah, it seems like a generator is the best way. but once it ends the iteration, how to start it, again, without creating a new one?
(Feb-18-2022, 02:53 AM)Skaperen Wrote: [ -> ]yeah, it seems like a generator is the best way. but once it ends the iteration, how to start it, again, without creating a new one?
A generator is just a function. You restart it by simply calling it a second time. Here's an example:
def calculate_squares (seed) :
while True :
yield seed * seed
seed += 1
square = calculate_squares (1)
for count in range (10) :
print (next (square), end = ' ')
print ()
# Reset the generator
square = calculate_squares (3)
print (next (square))
in a case i was working with, i could only call it once. once called the returned generator was passed along and that code needed to iterate over it 3 times. the simple solution was to make a list and use that 3 times. that worked but there were a couple of huge cases that caused some big swapping.
If you knew ahead of time at what point the generator should start over, I doesn't seem like it would be that difficult to write a generator function that you loop three times. Do you known what will trigger the generator to start over? A length, a flag, the StopIteration... ?
it would be used in a for loop, so it would be StopIteration.