1
$\begingroup$

This is a very basic question, but I searched through the official docs for list manipulation and on the site, and I wasn't able to find a specific function to delete item(s) by value from a list.

I'm currently using pattern substitution for that:

somelist := Flatten[{Range[-5,5],Range[-3,3]}]
somelist /. 0->Nothing
{-5,-4,-3,-2,-1,1,2,3,4,5,-3,-2,-1,1,2,3}

So, is pattern substitution the canonical way of deleting items by value, or will this hurt seasoned Mathematica users? What are the other solutions to delete items by value?

$\endgroup$
  • 2
    $\begingroup$ DeleteCases[0]@somelist? Extension: DeleteCases[-2 | 0 | 2]@somelist. $\endgroup$ – Michael E2 Dec 9 '19 at 1:21
  • 3
    $\begingroup$ DeleteCases is a common solution, as is its complementary function Cases. Select and Pick can be used, too, to filter a list. Nothing is relatively new to the language, so it won't appear in older code; however, it doesn't seem like a bad choice. Each approach has its virtues, and which to use might depend on the case at hand. For large packed arrays, this would be efficient for deleting 0: Pick[somelist, Unitize@somelist, 1]. $\endgroup$ – Michael E2 Dec 9 '19 at 1:57
  • 2
    $\begingroup$ Thank you very much for the explanations @Michael. This may eventually be useful for other people coming to Mathematica from another computer language. Would you consider posting that as an answer? $\endgroup$ – Sylvain Leroux Dec 9 '19 at 2:03
  • 1
    $\begingroup$ The way you remove zeros from your list is just fine. $\endgroup$ – m_goldberg Dec 9 '19 at 22:00
  • 2
    $\begingroup$ Yes, that's fine. I've been too busy to write up an answer. $\endgroup$ – Michael E2 Dec 10 '19 at 1:07
2
$\begingroup$

To synthesize what has been said in the comments to the question:

  • Several options are available, some of them making use of relatively new features of Mathematica
  • There isn't a strong consensus to decide if some solution is better style than the other

So in no particular order:

Map to Nothing

somelist /. 0->Nothing

Suggested by myself in the question

Works well, but Nothing being a relatively new addition to the language this solution won't appear in older code

In addition, Henrik Schumacher strongly discourage to get into the habit of using this solution large numerical data. The reason is "Nothing unpacks arrays." Henrik continues by saying, for large numerical data "usually the three-argument version of Pick is the fastest because that allows you to use a packed array as the second argument (unfortunately, Boolean arrays cannot be packed)"

Using Pick

Removing matching items is actually the same thing a picking only non matching items.

However, due to the way pattern matching is implemented, using Pick with Except can lead to surprising results. Here is a working solution:

Pick[somelist, somelist, Except[0, _Integer]]

Other possible uses of Pick to remove items are:

Pick[somelist, #!= 0 & /@ somelist ]
Pick[somelist,UnequalTo[0] /@  somelist ]
Pick[somelist,EqualTo[0] /@  somelist , False]

DeleteCases

DeleteCases[0]@somelist
DeleteCases[0|1|2]@somelist

Suggested by Michael E2

DeleteCases "is a common solution, as is its complementary function Cases. Select and Pick can be used, too, to filter a list"

Cases

Based on Michael's suggestions above, I would add:

Cases[somelist, Except[0]]

Select

Select[somelist, # != 0 &]
Select[somelist, UnequalTo[0]]
|improve this answer|||||
$\endgroup$

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