def split_where(seq, cut_test, key_func = None):
    """Split a sequence `seq` on every position `pos` between characters where cut_test(pos,a,b) is True,
       given a = seq[pos-1], b = seq[pos], 1 <= pos < len(seq).
       Return a list of subsequences, empty if `seq` is empty. `seq` must support iteration and slicing.
       If optional `key_func` is given, a list of (subseq, key_func(start,stop)) pairs is returned,
       where (start,stop) are start-stop indices of `subseq` in `seq`:
       start = index of subseq[0] in `seq`, stop = 1 + index of subseq[-1] in `seq`.
    
    Example of splitting a numeric sequence into monotonic (locally non-decreasing) subsequences:
    >>> split_where([1, 5, 8, 3, 5, 8, 2, 0, 4], lambda i, x, y: x > y)
    [[1, 5, 8], [3, 5, 8], [2], [0, 4]]
    >>> split_where([], None)
    []
    """
    result = []
    prev = None
    start = 0
    stop = -1
    
    # test every pair (a,b) of neighboring elements in `seq`, make a split wherever cut_test(a,b) is True
    for stop, curr in enumerate(seq):
        if stop >= 1 and cut_test(stop, prev, curr):
            subseq = seq[start:stop]
            item = subseq if key_func is None else (subseq, key_func(start, stop))
            result.append(item)
            start = stop
        prev = curr
    
    if stop == -1: return []                    # `seq` was empty?
    assert start <= stop
    # assert len(seq) == stop + 1
    
    subseq = seq[start:]
    item = subseq if key_func is None else (subseq, key_func(start, stop))
    result.append(item)
    
    return result