code: def __diff_iterable(self, level, parents_ids=frozenset({})):
          
          # We're handling both subscriptable and non-subscriptable iterables. Which one is it?
          subscriptable = self.__iterables_subscriptable(level.t1, level.t2)
          if subscriptable:
              child_relationship_class = SubscriptableIterableRelationship
          else:
              child_relationship_class = NonSubscriptableIterableRelationship
  
          for i, (x, y) in enumerate(
                  zip_longest(
                      level.t1, level.t2, fillvalue=ListItemRemovedOrAdded)):
              if y is ListItemRemovedOrAdded:  # item removed completely
                  change_level = level.branch_deeper(
                      x,
                      notpresent,
                      child_relationship_class=child_relationship_class,
                      child_relationship_param=i)
                  self.__report_result('iterable_item_removed', change_level)
  
              elif x is ListItemRemovedOrAdded:  # new item added
                  change_level = level.branch_deeper(
                      notpresent,
                      y,
                      child_relationship_class=child_relationship_class,
                      child_relationship_param=i)
                  self.__report_result('iterable_item_added', change_level)
  
              else:  # check if item value has changed
                  item_id = id(x)
                  if parents_ids and item_id in parents_ids:
                      continue
                  parents_ids_added = add_to_frozen_set(parents_ids, item_id)
  
                  # Go one level deeper
                  next_level = level.branch_deeper(
                      x,
                      y,
                      child_relationship_class=child_relationship_class,
                      child_relationship_param=i)
                  self.__diff(next_level, parents_ids_added)
docs: Difference of iterables