Splits "s" into substrings using "sep" as the delimiter string. Behaves like str.split, except that:

    1. Single strings are parsed into characters, any of which may be used as a delimiter
    2. Lists or tuples of multiple character strings may be provided, and thus used as delimiters

    If "sep" is None, a single character, or a list with one string, str.split is called directly.
    Otherwise, "s" is parsed iteratively until all delimiters have been found, or maxsplit has been reached.

    :param s: the unicode or binary string to split
    :param sep: a string or list of strings to use as delimiter in the split (defaults to whitespace):
        if a string, split on any char; if a list or tuple, split on any of its values
    :param maxsplit: if provided, the maximum number of splits to perform

    :return: the list of substrings in "s" between occurrences of "sep"

def splitany(s, sep=None, maxsplit=-1):
    """
    Splits "s" into substrings using "sep" as the delimiter string. Behaves like str.split, except that:

    1. Single strings are parsed into characters, any of which may be used as a delimiter
    2. Lists or tuples of multiple character strings may be provided, and thus used as delimiters

    If "sep" is None, a single character, or a list with one string, str.split is called directly.
    Otherwise, "s" is parsed iteratively until all delimiters have been found, or maxsplit has been reached.

    :param s: the unicode or binary string to split
    :param sep: a string or list of strings to use as delimiter in the split (defaults to whitespace):
        if a string, split on any char; if a list or tuple, split on any of its values
    :param maxsplit: if provided, the maximum number of splits to perform

    :return: the list of substrings in "s" between occurrences of "sep"
    """

    if s is None:
        return []
    elif not isinstance(s, STRING_TYPES):
        raise TypeError('Cannot split a {t}: {s}'.format(s=s, t=type(s).__name__))
    elif sep is None:
        return s.split(sep, maxsplit)
    elif not isinstance(sep, _split_sep_types):
        raise TypeError('Cannot split on a {t}: {s}'.format(s=sep, t=type(sep).__name__))
    else:
        split_on_any_char = isinstance(sep, STRING_TYPES)

        if split_on_any_char:
            # Python 3 compliance: sync and wrap to prevent issues with Binary: b'a'[0] == 97
            seps = [_sync_string_to(s, sep)]
        elif all(isinstance(sub, STRING_TYPES) for sub in sep):
            # Python 3 compliance: sync, but also sort keys by length to do largest matches first
            seps = [_sync_string_to(s, sub) for sub in sep]
        else:
            invalid_seps = [sub for sub in sep if not isinstance(sep, STRING_TYPES)]
            raise TypeError('Cannot split on the following: {s}'.format(s=invalid_seps))

    if len(s) == 0 or len(seps) == 0 or maxsplit == 0:
        return [s]
    elif len(seps) == 1:
        # Reduce to single char or list item
        # Call split if sep like: 'a', ['a'], ['ab']
        # Otherwise, split on any if sep like: 'ab'

        seps = seps[0]
        if not split_on_any_char or len(seps) == 1:
            return s.split(seps, maxsplit)

    as_text = isinstance(seps, _split_txt_types)
    parts = []
    start = 0
    rest = None

    try:
        while maxsplit < 0 or maxsplit >= len(parts):
            rest = s if start == 0 else rest[start:]

            # Sort based on (index_in_sep, negative_len_of_sep) to do largest matches first
            if as_text:
                stop = min((rest.index(sub), 0 - len(sub)) for sub in seps if sub in rest)
            else:
                # Python 3 compliance: iterating over bytes results in ints
                stop = min((rest.index(sub), 0 - len(bytes([sub]))) for sub in seps if sub in rest)

            parts.append(rest if maxsplit == len(parts) else rest[:stop[0]])
            start = stop[0] - stop[1]  # Skip full index of last delim

    except ValueError:
        parts.append(rest)

    return parts