Excluding different ranges or data points from a data set

If I have some list of data, I often want to remove individual points or chunks of data. I usually do this with Drop[...] but as far as I can tell, it isn't possible to drop multiple "regions". I often end up using nested drops -- which is a bit clumsy

Is there a better way to more intuitively and most importantly, flexibly select regions of a list to drop or exclude?

• How about Delete? Commented Dec 17, 2017 at 20:52

Maybe you can define your own drop function:

MyDrop[list_?ListQ, t : ( _Integer | ( _ ;; _)) ..] := Block[{idx},
idx = Replace[List[t], x_Integer -> x ;; x, 1];
idx = Apply[Union, Replace[idx, Span[x_, y_] :> Range[x, y], 1]];
Delete[list, Map[List, idx]]
];


Usage example:

MyDrop[Range[10], 5, 7 ;; 9, 6 ;; 8]


{1, 2, 3, 4, 10}

(Note that contrary to the other answers, any valid Drop syntax is supported)

dropList[expr_, pos__] := With[{indices = Range @ Length @ expr},
expr[[Complement[indices, Take[indices, #]& /@ Unevaluated[Sequence[pos]]]]]
]


For example:

dropList[Range[10], 2, 2;;6;;2, -2]


{3, 5, 7, 8}

Since I use Take to construct the elements to be deleted, any valid Drop (or Take) specification is supported. For example::

dropList[Range[20], 2, {4,6}, 9;;UpTo[100];;2]


{3, 7, 8, 10, 12, 14, 16, 18, 20}

Using Delete and Splice (new in 12.1)

DropPosition[v_, p_] :=
Delete[v, List /@ Splice @* Range @@@ List @@@ p]

DropPosition[Range[10], {{1, 1}, {3, 3}, {8, 10}}]


{2, 4, 5, 6, 7}

It also works with Span

DropPosition[Range[10], {2 ;; 3, 7 ;; 10}]


{1, 4, 5, 6}