code: def _replace_at_scopes(origin_list, scopes, new_items):
      r"""
      Replace items by ranges.
  
      :param list origin_list: the list value to be modified.
      :param list scopes: list of int/list/tuple/slice
          can be int indicate replace single item or their list like [1, 2, 3].
          can be list like (0,3) indicate replace items from 0 to 3(not included)
              or their list like [(0, 3), (5,6)]
          can be slice which would be convert to list or their list.
      Watch out! Each range must be the same type!
      :param list new_items: items corresponding scopes.
      :return list: new list
      """
  
      items = copy.deepcopy(origin_list)
      scopes = copy.deepcopy(scopes)
      assert isinstance(scopes, list), (
          f"The type of scopes should be `list`, "
          f"not {type(scopes)}."
      )
  
      if new_items is None:
          raise ValueError(f"Invalid replace input : {new_items}.")
  
      if len(new_items) != len(scopes):
          raise ValueError(
              f"Cannot replace {len(new_items)} tokens at {len(scopes)} ranges."
          )
  
      # ranges check
      for idx, scope_i in enumerate(scopes):
          scope_i = list(normalize_scope(scope_i))
          scope_i[0] = max(0, min(scope_i[0], len(items)))
          scope_i[1] = min(len(items), scope_i[1])
          scopes[idx] = scope_i
  
          if scope_i[0] >= scope_i[1]:
              raise ValueError(
                  f"No elements selected in range between "
                  f"{scope_i[0]} and {scope_i[1]}"
              )
  
      # check whether exist range collision
      def check_collision(r):
          for i, range1 in enumerate(r):
              for j, range2 in enumerate(r[i + 1 :]):
                  l1, r1 = range1
                  l2, r2 = range2
                  if max(l1, l2) < min(r1, r2):
                      return True
          return False
  
      if check_collision(scopes):
          raise ValueError(f"Ranges {scopes} has collision")
  
      real_items = []
  
      for idx, item in enumerate(new_items):
          next_item = item
          if not isinstance(item, (list, tuple)):
              next_item = [item]
          if item in [
              None,
              "",
              [],
          ]:  # Assume token is empty if it's ``None``, ``[]``, ``''``
              next_item = []
          real_items.append(list(next_item))
  
      sorted_items, sorted_scopes = zip(
          *sorted(zip(real_items, scopes), key=lambda x: x[1])
      )
      sorted_scopes = list(sorted_scopes)
      sorted_scopes.append([len(items), -1])
      replaced_items = items[: sorted_scopes[0][0]]
  
      for idx, sorted_token in enumerate(sorted_items):
          replaced_items.extend(sorted_token)
          replaced_items.extend(
              items[sorted_scopes[idx][1] : sorted_scopes[idx + 1][0]]
          )
  
      return replaced_items
  
imports: import copy
  import random
  from .logger import logger
label_desc: Use image node_id 3 for calling a global function with example usage: _replace_at_scopes(origin_list, scopes, new_items) and returns: replaced_items, False, True