1
$\begingroup$

Mathematica allows Deleting multiple objects from a list given their position. However, if I don't know their positions (finding their positions in the list is too costly if the list is long), how can I directly delete multiple objects from a List in an efficient manner (based on their value)?

$\endgroup$

marked as duplicate by Mr.Wizard list-manipulation Aug 14 '17 at 1:15

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 3
    $\begingroup$ DeleteCases is your friend. $\endgroup$ – halirutan Aug 14 '17 at 0:06
2
$\begingroup$

You can map the deleted values to Nothing with a Dispatch rule list.

someList = RandomInteger[{1, 5000}, 50000];
someDelList = RandomInteger[{1, 500}, 500];
someDelRules = Dispatch[Map[# -> Nothing &, someDelList]];

It can compare favorably timing wise with the naive overhead of sweeping through to find positions, then dropping those positions with Delete.

RepeatedTiming[someNewList1 = someList /. someDelRules;]

yields

{0.012, Null}

RepeatedTiming[
 someNewList2 = 
   Delete[someList, 
    Flatten[Position[someList, #] & /@ someDelList, 1]];]

yields

{1.72, Null}

With someNewList2 === someNewList1 $\mapsto$ True and Length[someNewList]$\mapsto$ 46862 .

Can also compare with a naive DeleteCases:

RepeatedTiming[
  someNewList3 = 
   DeleteCases[someList, (x_ /; !FreeQ[someDelList, x])];]

yielding:

{0.815, Null}

With also someNewList3 === someNewList1$\mapsto$True.

Update

Alternatives is the magic for DeleteCases.

  RepeatedTiming[
     someNewList4 = 
     DeleteCases[someList, Alternatives[someList]];]

yields

(.0053, Null)

Documentation here.

$\endgroup$

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