'Joins many lists or dicts of outputs into a single list or dict.
This function also validates that the outputs are correct for the given
Pipeline.
If `outputs` is a list of lists, the lists are concated and the type of
each object must match `unit.output_type`.
If `output` is a list of dicts (mapping string names to lists), each
key has its lists concated across all the dicts. The keys and types
are validated against `unit.output_type`.
Args:
outputs: A list of lists, or list of dicts which map string names to
lists.
unit: A Pipeline which every output in `outputs` will be validated
against. `unit` must produce the outputs it says it will produce.
Returns:
If `outputs` is a list of lists, a single list of outputs.
If `outputs` is a list of dicts, a single dictionary mapping string names
to lists of outputs.
Raises:
InvalidTransformOutputException: If anything in `outputs` does not match
the type signature given by `unit.output_type`.'

def _join_lists_or_dicts(self, outputs, unit):

    if (not outputs):
        return []
    if isinstance(unit.output_type, dict):
        concated = dict([(key, list()) for key in unit.output_type.keys()])
        for d in outputs:
            if (not isinstance(d, dict)):
                raise InvalidTransformOutputException(('Expected    dictionary    output    for    %s    with    output    type    %s    but    instead    got    type    %s' % (unit, unit.output_type, type(d))))
            if (set(d.keys()) != set(unit.output_type.keys())):
                raise InvalidTransformOutputException(('Got    dictionary    output    with    incorrect    keys    for    %s.    Got    %s.    Expected    %s' % (unit, d.keys(), unit.output_type.keys())))
            for (k, val) in d.items():
                if (not isinstance(val, list)):
                    raise InvalidTransformOutputException(('DagOutput    from    %s    for    key    %s    is    not    a    list.' % (unit, k)))
                if (not _all_are_type(val, unit.output_type[k])):
                    raise InvalidTransformOutputException(('Some    outputs    from    %s    for    key    %s    are    not    of    expected    type    %s.    Got    types    %s' % (unit, k, unit.output_type[k], [type(inst) for inst in val])))
                concated[k] += val
    else:
        concated = []
        for l in outputs:
            if (not isinstance(l, list)):
                raise InvalidTransformOutputException(('Expected    list    output    for    %s    with    outpu    type    %s    but    instead    got    type    %s' % (unit, unit.output_type, type(l))))
            if (not _all_are_type(l, unit.output_type)):
                raise InvalidTransformOutputException(('Some    outputs    from    %s    are    not    of    expected    type    %s.    Got    types    %s' % (unit, unit.output_type, [type(inst) for inst in l])))
            concated += l
    return concated
