5

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

Meqdad
  • 433
  • 3
  • 7
  • Cases[{0, f, y, e, 1, 2, 3}, Except[0]] – Pankaj Sejwal Feb 26 '14 at 15:46
  • 3
    DeleteCases[list,0] – Coolwater Feb 26 '14 at 16:12
  • 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. – Szabolcs Feb 26 '14 at 16:16

5 Answers5

11

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.)

Szabolcs
  • 234,956
  • 30
  • 623
  • 1,263
2
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}

eldo
  • 67,911
  • 5
  • 60
  • 168
2

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})

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
2

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}

bmf
  • 15,157
  • 2
  • 26
  • 63
2

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

bmf
  • 15,157
  • 2
  • 26
  • 63