I have set of values represented by a class. The class should be initialised with a generator to limit memory use.
The class itself is the iterable, having __iter__
, and the iterator, having __next__
(see below).
Since I want to be able to iterate over the set of values multiple times, I cache the generated values in a list. In __iter__
, I check if I already have iterated over all values, and then return iter
of the cached values, or self
to continue with next, respectively.
Here's the code stripped down to the relevant parts:
class SetOfValues(object):
def __init__(self, values):
self._values = values
self._values_generated = []
self._done = False
def __iter__(self):
if self._done:
return iter(self._values_generated)
else:
return self
def __next__(self):
try:
value = next(self._values)
self._values_generated.append(value)
return value
except StopIteration:
self._done = True
raise StopIteration("the end")
Then call it with:
x = SetOfValues((value for value in [1,2,3]))
for i in x:
print(i)
- Is this generally a good way to do it when you may need generated values more than once?
- Might it be better if
__iter__
yields the value? - In terms of usage of the class: might it be better to always rewind and let iter start with pos 0? Currently, iterating through the values, stopping early, then iterating again, would obviously just continue at the last index when not all values have been generated yet.
Thanks.