from typing import Iterable


def flatten(nested):
    """Flatten a nested sequence where the sub-items can be sequences or
    primitives. This differs slightly from itertools chain methods because
    those require all sub-items to be sequences. Here, items can be primitives,
    sequences, nested sequences, or any combination of these. Any iterable
    items aside from strings will be completely un-nested, so use with caution
    (e.g. a torch Dataset would be unpacked into separate items for each
    index). This also returns a list rather than a generator.

    Parameters
    ----------
    nested: sequence (list, tuple, set)
        Sequence where some or all of the items are also sequences.

    Returns
    -------
    list: Flattened version of `nested`.
    """
    def _walk(nested):
        for group in nested:
            if isinstance(group, Iterable) and not isinstance(group, str):
                yield from _walk(group)
            else:
                yield group
    return list(_walk(nested))