stgatilov

List-like semi-lazy container for lists and generators with concatenation

Jul 30th, 2026
25
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.13 KB | Source Code | 0 0
  1. # wraps an iterable into a lazy container
  2. # which can be iterated through as many times as wanted
  3. # and which evaluates elements on-demand and caches them internally
  4. class CachedIterable:
  5.     def __init__(self, iterable):
  6.         self.prefix = []
  7.         self.iterator = iter(iterable)
  8.  
  9.     def __iter__(self):
  10.         return self.Iterator(self)
  11.    
  12.     class Iterator:
  13.         def __init__(self, owner):
  14.             self.owner = owner
  15.             self.index = 0
  16.  
  17.         def __iter__(self):
  18.             return self
  19.        
  20.         def __next__(self):
  21.             if self.index < len(self.owner.prefix):
  22.                 ret = self.owner.prefix[self.index]
  23.             else:
  24.                 assert self.index == len(self.owner.prefix)
  25.                 ret = next(self.owner.iterator)
  26.                 self.owner.prefix.append(ret)
  27.             self.index += 1
  28.             return ret
  29.  
  30. # list-like container of children
  31. # it can be constructed from list and from generator,
  32. # and it can be composited using append and '+' like with lists
  33. class LazyArray:
  34.     def __init__(self, arr = None):
  35.         self.chunks = []
  36.         if arr is not None:
  37.             self.chunks.append(self._wrap_iterator(arr))
  38.  
  39.     def _wrap_iterator(self, arr):
  40.         assert not isinstance(arr, LazyArray)
  41.         if isinstance(arr, list):
  42.             return arr
  43.         assert hasattr(arr, '__iter__')
  44.         return CachedIterable(arr)
  45.  
  46.     def clear(self):
  47.         self.chunks.clear()
  48.  
  49.     def append(self, elem):
  50.         self.chunks.append([elem])
  51.  
  52.     def __add__(self, other):
  53.         if not isinstance(other, LazyArray):
  54.             other = LazyArray(other)
  55.         res = LazyArray()
  56.         res.chunks = self.chunks + other.chunks
  57.         return res
  58.  
  59.     def __radd__(self, other):
  60.         if not isinstance(other, LazyArray):
  61.             other = LazyArray(other)
  62.         res = LazyArray()
  63.         res.chunks = other.chunks + self.chunks
  64.         return res
  65.  
  66.     def __iter__(self):
  67.         for arr in self.chunks:
  68.             yield from arr
  69.  
  70.     def __bool__(self):
  71.         for i in self:
  72.             return True
  73.         return False
Advertisement
Add Comment
Please, Sign In to add comment