Stacks vals from a list of dicts into a dict of lists. Inserts Nones in
    place of empty items to preserve order.

    Args:
        dict_list (list): list of dicts
        key_suffix (str): (default = None)

    Returns:
        dict: stacked_dict

    Example:
        >>> # ENABLE_DOCTEST
        >>> # Usual case: multiple dicts as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': 1, 'b': 2}
        >>> dict2_ = {'a': 2, 'b': 3, 'c': 4}
        >>> dict_list = [dict1_, dict2_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [1, 2], 'b': [2, 3], 'c': [None, 4]}

    Example1:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: one dict as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': 1, 'b': 2}
        >>> dict_list = [dict1_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [1], 'b': [2]}

    Example2:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: zero dicts as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict_list = []
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {}

    Example3:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: empty dicts as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict_list = [{}]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {}

    Example4:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: one dict is empty
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': [1, 2], 'b': [2, 3]}
        >>> dict2_ = {}
        >>> dict_list = [dict1_, dict2_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [[1, 2], None], 'b': [[2, 3], None]}

    Example5:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: disjoint dicts
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': [1, 2], 'b': [2, 3]}
        >>> dict2_ = {'c': 4}
        >>> dict_list = [dict1_, dict2_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [[1, 2], None], 'b': [[2, 3], None], 'c': [None, 4]}

    Example6:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: 3 dicts
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict_list = [{'a': 1}, {'b': 1}, {'c': 1}, {'b': 2}]
        >>> default = None
        >>> dict_stacked = dict_stack2(dict_list, default=default)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [1, None, None, None], 'b': [None, 1, None, 2], 'c': [None, None, 1, None]}

def dict_stack2(dict_list, key_suffix=None, default=None):
    """
    Stacks vals from a list of dicts into a dict of lists. Inserts Nones in
    place of empty items to preserve order.

    Args:
        dict_list (list): list of dicts
        key_suffix (str): (default = None)

    Returns:
        dict: stacked_dict

    Example:
        >>> # ENABLE_DOCTEST
        >>> # Usual case: multiple dicts as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': 1, 'b': 2}
        >>> dict2_ = {'a': 2, 'b': 3, 'c': 4}
        >>> dict_list = [dict1_, dict2_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [1, 2], 'b': [2, 3], 'c': [None, 4]}

    Example1:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: one dict as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': 1, 'b': 2}
        >>> dict_list = [dict1_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [1], 'b': [2]}

    Example2:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: zero dicts as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict_list = []
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {}

    Example3:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: empty dicts as input
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict_list = [{}]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {}

    Example4:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: one dict is empty
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': [1, 2], 'b': [2, 3]}
        >>> dict2_ = {}
        >>> dict_list = [dict1_, dict2_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [[1, 2], None], 'b': [[2, 3], None]}

    Example5:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: disjoint dicts
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict1_ = {'a': [1, 2], 'b': [2, 3]}
        >>> dict2_ = {'c': 4}
        >>> dict_list = [dict1_, dict2_]
        >>> dict_stacked = dict_stack2(dict_list)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [[1, 2], None], 'b': [[2, 3], None], 'c': [None, 4]}

    Example6:
        >>> # ENABLE_DOCTEST
        >>> # Corner case: 3 dicts
        >>> from utool.util_dict import *  # NOQA
        >>> import utool as ut
        >>> dict_list = [{'a': 1}, {'b': 1}, {'c': 1}, {'b': 2}]
        >>> default = None
        >>> dict_stacked = dict_stack2(dict_list, default=default)
        >>> result = ut.repr2(dict_stacked)
        >>> print(result)
        {'a': [1, None, None, None], 'b': [None, 1, None, 2], 'c': [None, None, 1, None]}
    """
    if len(dict_list) > 0:
        dict_list_ = [map_dict_vals(lambda x: [x], kw) for kw in dict_list]
        # Reduce does not handle default quite correctly
        default1 = []
        default2 = [default]
        accum_ = dict_list_[0]
        for dict_ in dict_list_[1:]:
            default1.append(default)
            accum_ = dict_union_combine(accum_, dict_, default=default1,
                                        default2=default2)
        stacked_dict = accum_
        # stacked_dict = reduce(partial(dict_union_combine, default=[default]), dict_list_)
    else:
        stacked_dict = {}
    # Augment keys if requested
    if key_suffix is not None:
        stacked_dict = map_dict_keys(lambda x: x + key_suffix, stacked_dict)
    return stacked_dict