How do I split a list of numbers to monotonic sequences?

Starting at 10.1, there's a fairly neat solution using SequenceCases:

list = {1, 2, 4, 5, 7, 11, 8, 7, 3, 1, -3, -2, 6, 7, 80};
SequenceCases[list, x_ /; Less @@ x || Greater @@ x]
(* {{1, 2, 4, 5, 7, 11}, {8, 7, 3, 1, -3}, {-2, 6, 7, 80}} *)

This works because SequenceCases defaults to Overlaps -> False, such that e.g. 11 won't appear in two of the sublists.

Of course, if you want to allow repeated elements (i.e. not strictly monotonic sequences), use LessEqual and GreaterEqual respectively.

For a pre-10.1 solution using Split see Xavier's answer.


Martin provided a nice answer with SequenceCases. For Mathematica versions prior to 10.1, depending on what OP wants for lists of the form:

list2 = {1, 2, 4, 5, 7, 11, 8, 9, 10, 12, -3, -2, 6, 7, 80};

namely, for lists that have consecutive sequences of same monotonicity, an approach could be:

splitMon[list_] := 
    Split[list, 
        sign =.; 
        If[sign (#2 - #1) > 0, True, sign =.; False, sign = Sign[#2 - #1]; True] &
    ];

Examples:

SequenceCases[list, x_ /; Less @@ x || Greater @@ x]
% === splitMon[list]

(* {{1, 2, 4, 5, 7, 11}, {8, 7, 3, 1, -3}, {-2, 6, 7, 80}} *)
(* True *)

SequenceCases[list2, x_ /; Less @@ x || Greater @@ x]
% === splitMon[list2]

(* {{1, 2, 4, 5, 7, 11}, {8, 9, 10, 12}, {-3, -2, 6, 7, 80}} *)
(* True *)

Here's a solution using SplitBy. It works also for elements that are repeated no more than once, but it can be fixed if there are elements repeated more than once.

monotonicSplit[list_] := SplitBy[Transpose[{#, {#1, ##} & @@ Sign@Differences@#}] &@list, Last][[All, All, 1]]

list = {1, 2, 4, 5, 6, 6, 7, 3, 1, -3, -2, 6, 7, 80};
monotonicSplit[list]
(* {{1, 2, 4, 5, 6}, {6}, {7}, {3, 1, -3}, {-2, 6, 7, 80}} *)