6
$\begingroup$

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}}
$\endgroup$

8 Answers 8

9
$\begingroup$
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}}}

$\endgroup$
7
$\begingroup$

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}} *)
$\endgroup$
4
  • 1
    $\begingroup$ +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. $\endgroup$
    – WReach
    Apr 29, 2017 at 3:18
  • $\begingroup$ I have simplfied your answer to here.Hope don't mind that. $\endgroup$
    – yode
    Apr 29, 2017 at 4:25
  • $\begingroup$ @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. $\endgroup$
    – Pillsy
    Apr 29, 2017 at 20:22
  • $\begingroup$ @WReach good point, and a nice change! edited. $\endgroup$
    – Pillsy
    Apr 29, 2017 at 20:22
5
$\begingroup$

one option might be to use DeleteCases and then use Complement

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

Mathematica graphics

droppedList = Complement[list, newList]

Mathematica graphics

$\endgroup$
4
  • 2
    $\begingroup$ Out of curiosity, how is the first part better than newList = Select[list, First[#] > 3&]? $\endgroup$
    – Igor Rivin
    Apr 29, 2017 at 0:23
  • $\begingroup$ @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". $\endgroup$
    – Nasser
    Apr 29, 2017 at 0:40
  • $\begingroup$ 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. $\endgroup$
    – Igor Rivin
    Apr 29, 2017 at 0:51
  • $\begingroup$ @IgorRivin yes. Performance can always be a deciding factor on which method to use. $\endgroup$
    – Nasser
    Apr 29, 2017 at 0:53
5
$\begingroup$

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)&];
$\endgroup$
8
  • $\begingroup$ I thought Query[] was only supposed to work with Dataset?! $\endgroup$
    – Igor Rivin
    Apr 29, 2017 at 1:04
  • $\begingroup$ @IgorRivin It is the other way around... Dataset has a short form for expressing queries :) $\endgroup$
    – WReach
    Apr 29, 2017 at 1:11
  • $\begingroup$ 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. $\endgroup$
    – Igor Rivin
    Apr 29, 2017 at 1:37
  • $\begingroup$ There seem to be no non-Dataset examples... $\endgroup$
    – Igor Rivin
    Apr 29, 2017 at 1:37
  • 1
    $\begingroup$ @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). $\endgroup$
    – WReach
    Apr 29, 2017 at 3:13
4
$\begingroup$

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}}
$\endgroup$
3
$\begingroup$
Pick[list, (# > 3) & @@@ list, #] & /@ {False, True}

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

$\endgroup$
3
$\begingroup$

This approach uses SequenceCases

SequenceCases[list, {{_?(# <= 3 &)} ..} | {{_?(# > 3 &)} ..}]
(* {{{1}, {2}, {3}}, {{4}, {5}}} *)
$\endgroup$
2
$\begingroup$
{newList, dropList} = Through[{#[#[[1]] <= 3 &], #[#[[1]] > 3 &]}[lst]] & @ Select

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

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.