I got the following class, where:
iterable
is the passed argument, like for example range(20)
, n_max
is an optional value, which limits the numbers of elements the cache should have, iterator
is a field that gets initiated with the iterable, cache
is the list I am trying to fill and finished
is a bool
which signals if the iterator is "empty" or not. Here is an example input:
>>> iterable = range(20)
>>> cachedtuple = CachedTuple(iterable)
>>> print(cachedtuple[0])
0
>>> print(len(cachedtuple.cache))
1
>>> print(cachedtuple[10])
10
>>> print(len(cachedtuple.cache))
11
>>> print(len(cachedtuple))
20
>>> print(len(cachedtuple.cache))
20
>>> print(cachedtuple[25])
@dataclass
class CachedTuple:
iterable: Iterable = field(init=True)
n_max: Optional[int] = None
iterator: Iterator = field(init=False)
cache: list = field(default_factory=list)
finished: bool = False
def __post_init__(self):
self.iterator = iter(self.iterable)
def cache_next(self):
if self.n_max and self.n_max <= len(self.cache):
self.finished = True
else:
try:
nxt = next(self.iterator)
self.cache.append(nxt)
except StopIteration:
self.finished = True
def __getitem__(self, item: int):
match item:
case item if type(item) != int:
raise IndexError
case item if item < 0:
raise IndexError
case item if self.finished or self.n_max and item > self.n_max:
raise IndexError(f"Index {item} out of range")
case item if item >= len(self.cache):
while item - len(self.cache) >= 0:
self.cache_next()
return self.__getitem__(item)
case item if item < len(self.cache):
return self.cache[item]
def __len__(self):
while not self.finished:
self.cache_next()
return len(self.cache)
Although this code is certainly not good, at least it works for almost every scenario, but using the range function of Python for example. If I use for example
cachedtuple = CachedTuple(range(20))
for element in cachedtuple:
print(element)
I get the element until 19
and then the program loops infinitely. I think one problem might be that I have no raise StopIteration
in my code. So I am kind of lost how to fix this mess.
source https://stackoverflow.com/questions/70793606/custom-cache-with-iterator-does-not-work-as-intended
Comments
Post a Comment