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)?
Asked
Active
Viewed 317 times
1
1 Answers
2
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.
John Joseph M. Carrasco
- 3,190
- 12
- 19
DeleteCasesis your friend. – halirutan Aug 14 '17 at 00:06