code: def split_iterable_as_iterable(self, values):
          
          values = iter(enumerate(values))
          cache = dict()
          def get_value(ti):
              try:
                  return cache.pop(ti)
              except:
                  while True:
                      i, v = next(values)
                      if i==ti:
                          return v
                      cache[i] = v
          s = iter(self.index.sorter)
          for c in self.count:
              yield (get_value(i) for i in itertools.islice(s, int(c)))
docs: Group iterable into iterables, in the order of the keys
  
          Parameters
          ----------
          values : iterable of length equal to keys
              iterable of values to be grouped
  
          Yields
          ------
          iterable of items in values
  
          Notes
          -----
          Memory consumption depends on the amount of sorting required
          Worst case, if index.sorter[-1] = 0, we need to consume the entire value iterable,
          before we can start yielding any output
          But to the extent that the keys are already sorted, the grouping is lazy