Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # wraps an iterable into a lazy container
- # which can be iterated through as many times as wanted
- # and which evaluates elements on-demand and caches them internally
- class CachedIterable:
- def __init__(self, iterable):
- self.prefix = []
- self.iterator = iter(iterable)
- def __iter__(self):
- return self.Iterator(self)
- class Iterator:
- def __init__(self, owner):
- self.owner = owner
- self.index = 0
- def __iter__(self):
- return self
- def __next__(self):
- if self.index < len(self.owner.prefix):
- ret = self.owner.prefix[self.index]
- else:
- assert self.index == len(self.owner.prefix)
- ret = next(self.owner.iterator)
- self.owner.prefix.append(ret)
- self.index += 1
- return ret
- # list-like container of children
- # it can be constructed from list and from generator,
- # and it can be composited using append and '+' like with lists
- class LazyArray:
- def __init__(self, arr = None):
- self.chunks = []
- if arr is not None:
- self.chunks.append(self._wrap_iterator(arr))
- def _wrap_iterator(self, arr):
- assert not isinstance(arr, LazyArray)
- if isinstance(arr, list):
- return arr
- assert hasattr(arr, '__iter__')
- return CachedIterable(arr)
- def clear(self):
- self.chunks.clear()
- def append(self, elem):
- self.chunks.append([elem])
- def __add__(self, other):
- if not isinstance(other, LazyArray):
- other = LazyArray(other)
- res = LazyArray()
- res.chunks = self.chunks + other.chunks
- return res
- def __radd__(self, other):
- if not isinstance(other, LazyArray):
- other = LazyArray(other)
- res = LazyArray()
- res.chunks = other.chunks + self.chunks
- return res
- def __iter__(self):
- for arr in self.chunks:
- yield from arr
- def __bool__(self):
- for i in self:
- return True
- return False
Advertisement
Add Comment
Please, Sign In to add comment