code: def type_profile2(sequence, TypedSequence=None):
      
      if TypedSequence is None:
          TypedSequence = type_sequence_factory()
      # For a pure bottom level list return the length
      #if not any(map(util_type.is_listlike, sequence)) or (isinstance(sequence, np.ndarray) and sequence.dtype != object):
      if not util_type.is_listlike(sequence) or (isinstance(sequence, np.ndarray) and sequence.dtype != object):
          # Scalar / ndarray type
          if type(sequence) == 'numpy.ndarray':
              subtype_list = '[%s]' % (sequence.dtype,)
          else:
              subtype_list = None
          return TypedSequence(type(sequence), subtype_list)
      elif util_type.is_listlike(sequence):
          # Sequence type
          sequence_type = type(sequence)
  
          subtype_list = []
          for item in sequence:
              item_type_profile = type_profile2(item, TypedSequence=TypedSequence)
              subtype_list.append(item_type_profile)
          sequence_type_profile = TypedSequence(sequence_type, subtype_list)
          return sequence_type_profile
docs: similar to depth_profile but reports types
  
      Args:
          sequence (?):
          compress_homogenous (bool): (default = True)
  
      Returns:
          str: level_type_str
  
      CommandLine:
          python -m utool.util_list --exec-type_profile2
  
      Example:
          >>> # DISABLE_DOCTEST
          >>> sequence = []
          >>> from utool.util_list import *  # NOQA
          >>> self = typeprof = type_profile2(sequence, type_sequence_factory())
          >>> result = ('level_type_str = %s' % (str(level_type_str),))
          >>> print(result)