3
$\begingroup$

I have a very long nested list. Here is a short example:

list = {{1.2, {1, 1, 1, 1}, {2, 2, 2}}, {0.9, {3, 3, 3, 3}, {4, 4, 4}}, {1.4, {4, 4, 4, 4}, {5, 5, 5}}}

Now I want to cancel all entries if the first entry of each part of the list (list[[i]]) is > 1. So that the new list would only consist of the second part of list (list[[2]])

newlist = {0.9, {3, 3, 3, 3}, {4, 4, 4}}

I have already tried my luck with Position and Delete, but with no success.

Thanks a lot for your help!

$\endgroup$
6
  • $\begingroup$ Cases[list, {x_?NumericQ, a__} /; x <= 1 -> {x, a}] $\endgroup$ Commented Dec 20, 2013 at 16:09
  • $\begingroup$ It works great. Thanks a lot $\endgroup$
    – Anna
    Commented Dec 20, 2013 at 16:47
  • $\begingroup$ This is a very common type of question. (I may close it as a duplicate.) I agree with Pinguin Dirk's use of Pick, e.g. my own answers to (900) and (30155) $\endgroup$
    – Mr.Wizard
    Commented Dec 20, 2013 at 16:57
  • $\begingroup$ @belisarius That's too complicated; you need merely this: Cases[list, {x_, a__} /; x <= 1]. Also don't forget to use :> with named patterns! $\endgroup$
    – Mr.Wizard
    Commented Dec 20, 2013 at 17:21
  • $\begingroup$ I believe that the output you are looking for is a sublist of list, it should therefore be {{0.9, {3, 3, 3, 3}, {4, 4, 4}}} (note the extra {}) -- Unless you know that only one item will be selected. $\endgroup$
    – A.G.
    Commented Dec 20, 2013 at 18:42

5 Answers 5

2
$\begingroup$

Rather than think of it as deleting certain unwanted parts of the list, you can equivalently think of it as selecting the parts you wish to keep. Accordingly, Select can be straightforwardly applied

Select[list, #[[1]] < 1 &]
{{0.9, {3, 3, 3, 3}, {4, 4, 4}}}

A. G. points out that this can be made more transparent by replacing the perhaps somewhat cryptic Part command [[1]] with

Select[list, First[#] < 1 &]

You can Flatten[%, 1] if you wish to get the levels exactly as described in the question.

$\endgroup$
1
  • $\begingroup$ Note that #[[1]] can also be written First[#] or First@# or even (# // First) !!! $\endgroup$
    – A.G.
    Commented Dec 20, 2013 at 18:14
3
$\begingroup$

A solution using Pick:

Pick[list, UnitStep[list[[All, 1]] - 1], 0]

(I subtract one from the first element and then grab all positions with a negative such element)

$\endgroup$
1
  • $\begingroup$ Great idea. Thanks a lot $\endgroup$
    – Anna
    Commented Dec 20, 2013 at 16:49
1
$\begingroup$
list = {{1.2, {1, 1, 1, 1}, {2, 2, 2}},
        {0.9, {3, 3, 3, 3}, {4, 4, 4}},
        {1.4, {4, 4, 4, 4}, {5, 5, 5}}};

Using Replace:

Replace[list, {a_ /; a > 1, ___} :> Nothing, {1}]

(*{{0.9, {3, 3, 3, 3}, {4, 4, 4}}}*)
$\endgroup$
1
$\begingroup$
list = 
 {{1.2, {1, 1, 1, 1}, {2, 2, 2}}, 
  {0.9, {3, 3, 3, 3}, {4, 4, 4}}, 
  {1.4, {4, 4, 4, 4}, {5, 5, 5}}};

via Position

p = Position[list, {x_ /; x > 1, __}, 1]

{{1}, {3}}

Using Delete

Delete[p] @ list

{{0.9, {3, 3, 3, 3}, {4, 4, 4}}}

Using ReplaceAt (new in 13.1)

ReplaceAt[_ :> Nothing, p] @ list

{{0.9, {3, 3, 3, 3}, {4, 4, 4}}}

$\endgroup$
1
$\begingroup$

Using Sow/Reap:

list = {{1.2, {1, 1, 1, 1}, {2, 2, 2}}, {0.9, {3, 3, 3, 3}, {4, 4, 
    4}}, {1.4, {4, 4, 4, 4}, {5, 5, 5}}}

Scan[
    If[First@# < 1, Sow@#, Nothing] &
    , list] //
   Reap // Last // First

{{0.9, {3, 3, 3, 3}, {4, 4, 4}}}

$\endgroup$

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.