class_docstr: Iterator for sharding a list of Episodes into num_shards sub-lists of Episodes.
  
  Args:
      episodes: The input list of Episodes.
      num_shards: The number of shards to split the episodes into.
  
  Yields:
      A sub-list of Episodes of size roughly `len(episodes) / num_shards`. The yielded
      sublists might have slightly different total sums of episode lengths, in order
      to not have to drop even a single timestep.
code: def __init__(self, episodes: List[EpisodeType], num_shards: int):
      self._episodes = sorted(episodes, key=len, reverse=True)
      self._num_shards = num_shards
      self._total_length = sum(len(e) for e in episodes)
      self._target_lengths = [0 for _ in range(self._num_shards)]
      remaining_length = self._total_length
      for s in range(self._num_shards):
          len_ = remaining_length // (num_shards - s)
          self._target_lengths[s] = len_
          remaining_length -= len_
  
imports: import math
  from typing import List
  from ray.rllib.policy.sample_batch import MultiAgentBatch, concat_samples
  from ray.rllib.policy.sample_batch import SampleBatch
  from ray.rllib.utils.annotations import DeveloperAPI
  from ray.rllib.utils.typing import EpisodeType
label_desc: Use image node_id 1 to create a new ShardEpisodesIterator object  with example: obj = ShardEpisodesIterator(episodes, num_shards)