r"""
    Args:
        unflat_list (list):

    Returns:
        tuple: (flat_list, invert_levels)

    CommandLine:
        python -m utool.util_list --exec-invertible_total_flatten --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_list import *  # NOQA
        >>> import utool as ut
        >>> unflat_list = [0, [[1, 2, 3], 4, 5], 9, [2, 3], [1, [2, 3, 4]], 1, 2, 3]
        >>> print('unflat_list = %r' % (unflat_list,))
        >>> (flat_list, invert_levels) = invertible_total_flatten(unflat_list)
        >>> print('flat_list = %r' % (flat_list,))
        >>> unflat_list2 = total_unflatten(flat_list, invert_levels)
        >>> print('unflat_list2 = %r' % (unflat_list2,))
        >>> assert unflat_list2 == unflat_list
        >>> assert ut.depth_profile(flat_list) == 16

def invertible_total_flatten(unflat_list):
    r"""
    Args:
        unflat_list (list):

    Returns:
        tuple: (flat_list, invert_levels)

    CommandLine:
        python -m utool.util_list --exec-invertible_total_flatten --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from utool.util_list import *  # NOQA
        >>> import utool as ut
        >>> unflat_list = [0, [[1, 2, 3], 4, 5], 9, [2, 3], [1, [2, 3, 4]], 1, 2, 3]
        >>> print('unflat_list = %r' % (unflat_list,))
        >>> (flat_list, invert_levels) = invertible_total_flatten(unflat_list)
        >>> print('flat_list = %r' % (flat_list,))
        >>> unflat_list2 = total_unflatten(flat_list, invert_levels)
        >>> print('unflat_list2 = %r' % (unflat_list2,))
        >>> assert unflat_list2 == unflat_list
        >>> assert ut.depth_profile(flat_list) == 16

    """
    import utool as ut
    next_list = unflat_list
    scalar_flags = [not ut.isiterable(item) for item in next_list]
    invert_stack = []
    # print('unflat_list = %r' % (unflat_list,))
    while not all(scalar_flags):
        unflattenized = [[item] if flag else item
                         for flag, item in zip(scalar_flags, next_list)]
        flatter_list, invert_part = ut.invertible_flatten1(unflattenized)
        # print('flatter_list = %r' % (flatter_list,))
        for idx in ut.where(scalar_flags):
            invert_part[idx] = invert_part[idx][0]
        invert_stack.append(invert_part)
        next_list = flatter_list
        scalar_flags = [not ut.isiterable(item) for item in next_list]
    # invert_part = [None] * len(scalar_flags)
    # invert_stack.append(invert_part)
    invert_levels = invert_stack[::-1]
    flat_list = next_list
    return flat_list, invert_levels