class_docstr: More efficient ops for indices.
  
  Avoid wasteful allocations, accept generators. Convert to list only
  when needed.
  
  Do not use for anything outside this file.
code: def __init__(self, *lists, known_length=None, offset=0):
      new_lists = []
      for ll in lists:
          if isinstance(ll, LazyIndices) and ll._eager_list is not None:
              # already eagerized, don't waste work
              new_lists.append(ll._eager_list)
          else:
              new_lists.append(ll)
      self._lists = new_lists  # freed after eagerification
  
      if len(new_lists) == 1 and offset == 0:
          self._eager_list = new_lists[0]
      else:
          self._lazy_sequence = itertools.chain(*new_lists)
          """chain of generators
              this will be consumed over time whenever we need elems.
              """
          self._eager_list = None
          """This is the list where we save indices
              whenever we generate them from the lazy sequence.
              """
          self._offset = offset
  
      # check depth to avoid RecursionError
      if self._depth() > sys.getrecursionlimit() // 4:
          self._to_eager()
  
      if known_length is not None:
          self._known_length = known_length
      elif self._eager_list is not None:
          self._known_length = len(self._eager_list)
      else:
          self._known_length = sum(len(ll) for ll in new_lists)
  
imports: import bisect
  import sys
  import numpy
  from avalanche.benchmarks.utils.dataset_utils import slice_alike_object_to_indices
  from typing import Iterable, List, Optional, Sequence, Tuple, TypeVar, Union, overload
  from torch.utils.data import ConcatDataset
  import itertools
  from avalanche.benchmarks.utils.dataset_definitions import IDataset
label_desc: Use image node_id 1 to create a new LazyIndices object  with example: obj = LazyIndices()