5
$\begingroup$

I have a list containing zero and nonzero elements. How can I throw away zero elements and just keep non zero ones.

$\endgroup$
3
  • $\begingroup$ Cases[{0, f, y, e, 1, 2, 3}, Except[0]] $\endgroup$ Feb 26, 2014 at 15:46
  • 3
    $\begingroup$ DeleteCases[list,0] $\endgroup$
    – Coolwater
    Feb 26, 2014 at 16:12
  • $\begingroup$ Instead of either of the two suggestions above, I recommend Select[list, # != 0 &] for the reason that pattern matching differentiates between 0. and 0 while == has a small tolerance even for machine precision zeros. Pattern matching can be fixed by using 0|0. in place of 0. $\endgroup$
    – Szabolcs
    Feb 26, 2014 at 16:16

5 Answers 5

11
$\begingroup$

Use

Select[list, # != 0 &]

for the simplest solution.


A non-obvious solution that can be quite fast (for versions $\ge 8$), especially for packed arrays, is

Pick[list, Unitize[list], 1]

This'll give you better performance than Select.


A warning about pattern matching: it differentiates between exact 0 and inexact 0., thus

In[2]:= DeleteCases[{0., 0, 1}, 0]
Out[2]= {0., 1}

In[3]:= DeleteCases[{0., 0, 1}, 0.]
Out[3]= {0, 1}

You can use the pattern 0|0. but using comparison (== or !=) is both clearer and == allows for greater differences from zero (that might arise due to numerical roundoff errors during calculations) than === and pattern matching. So I recommend ==. (You might google for Internal`$EqualTolerance and Internal`$SameQTolerance if you wish to learn about these tolerances.)

$\endgroup$
2
$\begingroup$
list = {0, 0.0, 0 + 0 I, f, y, e, 1, 2, 3};

Using PossibleZeroQ

Select[Not @* PossibleZeroQ] @ list

{f, y, e, 1, 2, 3}

$\endgroup$
2
$\begingroup$

Grabbing the list from @eldo

list = {0, 0.0, 0 + 0 I, f, y, e, 1, 2, 3};
list /. x_ /; x == 0 -> Nothing

{f, y, e, 1, 2, 3}

$\endgroup$
2
$\begingroup$

And another one is:

foo[list_] := 
  Module[{nonzeropositions, nonzeroelements}, 
   nonzeropositions = Flatten[SparseArray[list]["NonzeroPositions"]];
   nonzeroelements = list[[nonzeropositions]];
   Print["The non-zero elements of the list are:"];
   Return[nonzeroelements];];

which we test with ---again the list is from @eldo

test = {0, 0.0, 0 + 0 I, f, y, e, 1, 2, 3};

Now, we run

foo[test]

and we get

foo

$\endgroup$
2
$\begingroup$

Grabbing the list from @eldo and using Extract, Position and PossibleZeroQ:

list = {0, 0.0, 0 + 0 I, f, y, e, 1, 2, 3};

Extract[#, Position[#, x_ /; ! PossibleZeroQ[x], Heads -> False]] &@list

(*{f, y, e, 1, 2, 3}*)
$\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.