# Drop From One list and Take in other list

Suppose I have a list,

list = Table[{n}, {n, 1, 5}]
(*list = {{1},{2},{3},{4},{5}}*)


and I want to remove all values from this list that are greater than 3, so that I get

newlist = {{1}, {2}, {3}}


But the other values should be saved in another list called the drop list to this below as shown

droplist = {{4},{5}}


TakeDrop[sort = Sort[list], LengthWhile[sort, First[#] < 4 &]]


{{{1},{2},{3}},{{4},{5}}}

As the reminder of Pillsy's answer here

GatherBy[list, 3 < First[#1] &]


{{{1}, {2}, {3}}, {{4}, {5}}}

You can use GroupBy and Lookup to make sure that the two returned lists are in the order you expect:

{newlist, droplist} =
Lookup[GroupBy[list, 3 < First[#1] & ], {False, True}, {}];


The third argument to Lookup makes sure an empty list is returned if there aren't any True or False elements, instead of a potentially annoying Missing object.

newlist
(* {{1}, {2}, {3}} *)

droplist
(* {{4}, {5}} *)

• +1 If needed, we could account for one of the lists being empty by adding {} as the third default argument to Lookup. This is my favourite answer so far. – WReach Apr 29 '17 at 3:18
• I have simplfied your answer to here.Hope don't mind that. – yode Apr 29 '17 at 4:25
• @yode the only problem with that simplification is it won't always return the lists in the same order, so you won't always know which is newlist and which is droplist. – Pillsy Apr 29 '17 at 20:22
• @WReach good point, and a nice change! edited. – Pillsy Apr 29 '17 at 20:22

one option might be to use DeleteCases and then use Complement

list = Table[{n}, {n, 1, 5}]
newList = DeleteCases[list, {x_} /; x > 3]


droppedList = Complement[list, newList]


• Out of curiosity, how is the first part better than newList = Select[list, First[#] > 3&]? – Igor Rivin Apr 29 '17 at 0:23
• @IgorRivin in Mathematica, the rule of thumb is: there are at least 10 different ways to do same thing. Now which one of these 10 ways is "better" than the other left to the reader to decide and can depend on many things. They can also all be equally "good". – Nasser Apr 29 '17 at 0:40
• There could be a major performance difference. In fact, there is none between our two ways (for al list of length 5000000, your method takes 4.02137 seconds, and mine 4.36038 seconds (both pretty pathetic on modern hardware). By contrast, WReach's method (in the other answer) takes 8.75143 seconds. – Igor Rivin Apr 29 '17 at 0:51
• @IgorRivin yes. Performance can always be a deciding factor on which method to use. – Nasser Apr 29 '17 at 0:53

Here is a way that uses Query:

{dropList, newList} = list // Query[Select /@ {#, Not@*#}] &[#[[1]] > 3 &];

newList
(* {{1}, {2}, {3}} *)

dropList
(* {{4}, {5}} *)


... and another way that uses a double Reap to collect values sown from a single Scan:

Reap[Reap[Scan[Sow[#, #[[1]]>3]&, list], False, (newList=#2)&], True, (dropList=#2)&];

• I thought Query[] was only supposed to work with Dataset?! – Igor Rivin Apr 29 '17 at 1:04
• @IgorRivin It is the other way around... Dataset has a short form for expressing queries :) – WReach Apr 29 '17 at 1:11
• This is what the documentation says: Query[Subscript[operator, 1],Subscript[operator, 2],\[Ellipsis]] represents a query that can be applied to a Dataset object, in which the successive Subscript[operator, i] are applied at successively deeper levels. – Igor Rivin Apr 29 '17 at 1:37
• There seem to be no non-Dataset examples... – Igor Rivin Apr 29 '17 at 1:37
• @IgorRivin It also says: Query can operate on a Dataset object or an arbitrary nested expression consisting of lists and associations. In fact, it can operate upon any expression as it is simply an alternate syntax for composing operators -- as it can be seen as a generalization of Part. Virtually none of the examples under Query involve Dataset (there is one in the last section). – WReach Apr 29 '17 at 3:13

In:

xss = Range[5] // Map[List]
yss = xss // Select[# <= 3 & @@ # &]
zss = Complement[xss, yss]


Out:

{{1}, {2}, {3}, {4}, {5}}
{{1}, {2}, {3}}
{{4}, {5}}

Pick[list, (# > 3) & @@@ list, #] & /@ {False, True}


{{{1}, {2}, {3}}, {{4}, {5}}}

This approach uses SequenceCases

SequenceCases[list, {{_?(# <= 3 &)} ..} | {{_?(# > 3 &)} ..}]
(* {{{1}, {2}, {3}}, {{4}, {5}}} *)

{newList, dropList} = Through[{#[#[[1]] <= 3 &], #[#[[1]] > 3 &]}[lst]] & @ Select


{{{1}, {2}, {3}}, {{4}, {5}}}

• Note the element should be #<3& – yode Apr 29 '17 at 4:34
• @yode, I've taken it into consideration now ))) – garej Apr 29 '17 at 4:57