r"""
    Returns a nested list corresponding the shape of the nested structures
    lists represent depth, tuples represent shape. The values of the items do
    not matter. only the lengths.

    Args:
        list_ (list):
        max_depth (None):
        compress_homogenous (bool):
        compress_consecutive (bool):  experimental

    CommandLine:
        python -m utool.util_list --test-depth_profile

    Setup:
        >>> from utool.util_list import *  # NOQA

    Example0:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]]
        >>> result = depth_profile(list_)
        >>> print(result)
        (2, 3, 4)

    Example1:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[[[1]]], [3, 4, 33]], [[1], [2, 3], [4, [5, 5]]], [1, 3]]
        >>> result = depth_profile(list_)
        >>> print(result)
        [[(1, 1, 1), 3], [1, 2, [1, 2]], 2]

    Example2:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[[[1]]], [3, 4, 33]], [[1], [2, 3], [4, [5, 5]]], [1, 3]]
        >>> result = depth_profile(list_, max_depth=1)
        >>> print(result)
        [[(1, '1'), 3], [1, 2, [1, '2']], 2]

    Example3:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[1, 2], [1, 2, 3]], None]
        >>> result = depth_profile(list_, compress_homogenous=True)
        >>> print(result)
        [[2, 3], 1]

    Example4:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [9, 5, 3], [2, 2]]
        >>> result = depth_profile(list_, compress_homogenous=True, compress_consecutive=True)
        >>> print(result)
        [2] * 6 + [3, 2]

    Example5:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[3, 9], 2], [[3, 9], 2], [[3, 9], 2], [[3, 9], 2]]  #, [3, 2], [3, 2]]
        >>> result = depth_profile(list_, compress_homogenous=True, compress_consecutive=True)
        >>> print(result)
        (4, [2, 1])

    Example6:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[[1, 2]], [1, 2]], [[[1, 2]], [1, 2]], [[[0, 2]], [1]]]
        >>> result1 = depth_profile(list_, compress_homogenous=True, compress_consecutive=False)
        >>> result2 = depth_profile(list_, compress_homogenous=True, compress_consecutive=True)
        >>> result = str(result1) + '\n' + str(result2)
        >>> print(result)
        [[(1, 2), 2], [(1, 2), 2], [(1, 2), 1]]
        [[(1, 2), 2]] * 2 + [[(1, 2), 1]]

    Example7:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[{'a': [1, 2], 'b': [3, 4, 5]}, [1, 2, 3]], None]
        >>> result = depth_profile(list_, compress_homogenous=True)
        >>> print(result)

    Example8:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[1]], [[[1, 1], [1, 1]]], [[[[1, 3], 1], [[1, 3, 3], 1, 1]]]]
        >>> result = depth_profile(list_, compress_homogenous=True)
        >>> print(result)

    Example9:
        >>> # ENABLE_DOCTEST
        >>> list_ = []
        >>> result = depth_profile(list_)
        >>> print(result)

        # THIS IS AN ERROR???
        SHOULD BE
        #[1, 1], [1, 2, 2], (1, ([1, 2]), (

    Example10:
        >>> # ENABLE_DOCTEST
        >>> fm1 = [[0, 0], [0, 0]]
        >>> fm2 = [[0, 0], [0, 0], [0, 0]]
        >>> fm3 = [[0, 0], [0, 0], [0, 0], [0, 0]]
        >>> list_ = [0, 0, 0]
        >>> list_ = [fm1, fm2, fm3]
        >>> max_depth = 0
        >>> new_depth = True
        >>> result = depth_profile(list_, max_depth=max_depth, new_depth=new_depth)
        >>> print(result)

def depth_profile(list_, max_depth=None, compress_homogenous=True, compress_consecutive=False, new_depth=False):
    r"""
    Returns a nested list corresponding the shape of the nested structures
    lists represent depth, tuples represent shape. The values of the items do
    not matter. only the lengths.

    Args:
        list_ (list):
        max_depth (None):
        compress_homogenous (bool):
        compress_consecutive (bool):  experimental

    CommandLine:
        python -m utool.util_list --test-depth_profile

    Setup:
        >>> from utool.util_list import *  # NOQA

    Example0:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]], [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]]]
        >>> result = depth_profile(list_)
        >>> print(result)
        (2, 3, 4)

    Example1:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[[[1]]], [3, 4, 33]], [[1], [2, 3], [4, [5, 5]]], [1, 3]]
        >>> result = depth_profile(list_)
        >>> print(result)
        [[(1, 1, 1), 3], [1, 2, [1, 2]], 2]

    Example2:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[[[1]]], [3, 4, 33]], [[1], [2, 3], [4, [5, 5]]], [1, 3]]
        >>> result = depth_profile(list_, max_depth=1)
        >>> print(result)
        [[(1, '1'), 3], [1, 2, [1, '2']], 2]

    Example3:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[1, 2], [1, 2, 3]], None]
        >>> result = depth_profile(list_, compress_homogenous=True)
        >>> print(result)
        [[2, 3], 1]

    Example4:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [3, 2], [9, 5, 3], [2, 2]]
        >>> result = depth_profile(list_, compress_homogenous=True, compress_consecutive=True)
        >>> print(result)
        [2] * 6 + [3, 2]

    Example5:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[3, 9], 2], [[3, 9], 2], [[3, 9], 2], [[3, 9], 2]]  #, [3, 2], [3, 2]]
        >>> result = depth_profile(list_, compress_homogenous=True, compress_consecutive=True)
        >>> print(result)
        (4, [2, 1])

    Example6:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[[1, 2]], [1, 2]], [[[1, 2]], [1, 2]], [[[0, 2]], [1]]]
        >>> result1 = depth_profile(list_, compress_homogenous=True, compress_consecutive=False)
        >>> result2 = depth_profile(list_, compress_homogenous=True, compress_consecutive=True)
        >>> result = str(result1) + '\n' + str(result2)
        >>> print(result)
        [[(1, 2), 2], [(1, 2), 2], [(1, 2), 1]]
        [[(1, 2), 2]] * 2 + [[(1, 2), 1]]

    Example7:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[{'a': [1, 2], 'b': [3, 4, 5]}, [1, 2, 3]], None]
        >>> result = depth_profile(list_, compress_homogenous=True)
        >>> print(result)

    Example8:
        >>> # ENABLE_DOCTEST
        >>> list_ = [[[1]], [[[1, 1], [1, 1]]], [[[[1, 3], 1], [[1, 3, 3], 1, 1]]]]
        >>> result = depth_profile(list_, compress_homogenous=True)
        >>> print(result)

    Example9:
        >>> # ENABLE_DOCTEST
        >>> list_ = []
        >>> result = depth_profile(list_)
        >>> print(result)

        # THIS IS AN ERROR???
        SHOULD BE
        #[1, 1], [1, 2, 2], (1, ([1, 2]), (

    Example10:
        >>> # ENABLE_DOCTEST
        >>> fm1 = [[0, 0], [0, 0]]
        >>> fm2 = [[0, 0], [0, 0], [0, 0]]
        >>> fm3 = [[0, 0], [0, 0], [0, 0], [0, 0]]
        >>> list_ = [0, 0, 0]
        >>> list_ = [fm1, fm2, fm3]
        >>> max_depth = 0
        >>> new_depth = True
        >>> result = depth_profile(list_, max_depth=max_depth, new_depth=new_depth)
        >>> print(result)
    """
    if isinstance(list_, dict):
        list_ = list(list_.values())   # handle dict
    level_shape_list = []
    # For a pure bottom level list return the length
    if not any(map(util_type.is_listlike, list_)):
        return len(list_)

    if False and new_depth:
        pass
        # max_depth_ = None if max_depth is None else max_depth - 1
        # if max_depth_ is None or max_depth_ > 0:
        #     pass
        # else:
        #     for item in list_:
        #         if isinstance(item, dict):
        #             item = list(item.values())  # handle dict
        #         if util_type.is_listlike(item):
        #             if max_depth is None:
        #                 level_shape_list.append(depth_profile(item, None))
        #             else:
        #                 if max_depth >= 0:
        #                     level_shape_list.append(depth_profile(item, max_depth - 1))
        #                 else:
        #                     level_shape_list.append(str(len(item)))
        #         else:
        #             level_shape_list.append(1)
    else:
        for item in list_:
            if isinstance(item, dict):
                item = list(item.values())  # handle dict
            if util_type.is_listlike(item):
                if max_depth is None:
                    level_shape_list.append(depth_profile(item, None))
                else:
                    if max_depth >= 0:
                        level_shape_list.append(depth_profile(item, max_depth - 1))
                    else:
                        level_shape_list.append(str(len(item)))
            else:
                level_shape_list.append(1)

    if compress_homogenous:
        # removes redudant information by returning a shape duple
        if allsame(level_shape_list):
            dim_ = level_shape_list[0]
            len_ = len(level_shape_list)
            if isinstance(dim_, tuple):
                level_shape_list = tuple([len_] + list(dim_))
            else:
                level_shape_list = tuple([len_, dim_])

    if compress_consecutive:
        hash_list = list(map(hash, map(str, level_shape_list)))
        consec_list = group_consecutives(hash_list, 0)
        if len(consec_list) != len(level_shape_list):
            len_list = list(map(len, consec_list))
            cumsum_list = np.cumsum(len_list)
            consec_str = '['
            thresh = 1
            for len_, cumsum in zip(len_list, cumsum_list):
                value = level_shape_list[cumsum - 1]
                if len_ > thresh:
                    consec_str += str(value) + '] * ' + str(len_)
                    consec_str += ' + ['
                else:
                    consec_str += str(value) + ', '
            if consec_str.endswith(', '):
                consec_str = consec_str[:-2]
                #consec_str += ']'
            #consec_str = consec_str.rstrip(', ').rstrip(']')
            #consec_str = consec_str.rstrip(', ')
            #if consec_str.endswith(']'):
            #    consec_str = consec_str[:-1]
            consec_str += ']'
            level_shape_list = consec_str
    return level_shape_list