2
$\begingroup$

If I have an list of numbers {1, 2, 4, 70, 11, 20, 56, 79}, is there a way to remove the list {2, 4, 56} from that list?

In my application, the lists are way bigger, so I am looking for a general way of removing a list of numbers from the original list.

My thoughts were to use the following code: DeleteCases[{1, 2, 4, 70, 11, 20, 56, 79}, {2, 4, 56}] but that didn't work, because the output must be {1, 70, 11, 20, 79} and it isn't.

$\endgroup$
4
  • 1
    $\begingroup$ You coud try: DeleteCases[{1, 2, 4, 70, 11, 20, 56, 79}, x_ /; MemberQ[{2, 4, 56}, x]] $\endgroup$ – Daniel Huber Jan 13 at 17:20
  • 5
    $\begingroup$ Just a little correction of your code DeleteCases[{1, 2, 4, 70, 11, 20, 56, 79}, Alternatives@@{2,4,56}] should do the trick. $\endgroup$ – Roma Lee Jan 13 at 17:44
  • 1
    $\begingroup$ Strongly related: How to Delete Elements from List1 appearing in List2? $\endgroup$ – user1066 Jan 13 at 18:00
  • 1
    $\begingroup$ Also, unsorted complement $\endgroup$ – user1066 Jan 13 at 18:02
5
$\begingroup$

There are three main ways of deleting members in such cases :

  1. As Daniel said , you could try DeleteCases supplementing a pattern which picks up just the numbers which are element of another list. The pattern is like this :

as what Daniel said :

a_ /; MemberQ[{2,4,56},a]

or :

a_?(MemberQ[{2, 4, 56}, #] &)

Now you could use each one of the above patterns in DeleteCases. Thus we have :

DeleteCases[{1, 2, 4, 70, 11, 20, 56, 79} , a_ /; MemberQ[{2,4,56},a])]

or :

DeleteCases[{1, 2, 4, 70, 11, 20, 56, 79} , a_?(MemberQ[{2, 4, 56}, #] &)]
  1. But there is even a simpler way of deleting cases which could be tried.

This is a sample :

{1, 2, 4, 70, 11, 20, 56, 79} /. a_ /; MemberQ[{2, 4, 56}, a] -> Nothing

In this way we could just convert any instance matching your pattern to Nothing ! ( Converting THING to NOTHING. isn't better?! )

  1. And even simpler :

Just using Complement :

Complement[{1, 2, 4, 70, 11, 20, 56, 79}, {2, 4, 56}]

BE CAUTIONED !! Using each one of the mentioned ways WILL NOT take the same (asymptotically) time to evaluate.

Just for representation , we could compare these two ways in list with length of 10^6 :

For the first route :

AbsoluteTiming[
  Table[DeleteCases[Range[10^6], 
     a_?(MemberQ[RandomInteger[10^6, 100], #] &)];, 5]] // First

which gives me 124.474 (means 124 seconds).

And for the second way:

AbsoluteTiming[
  Table[Range[10^6] /. 
     a_ /; MemberQ[RandomInteger[10^6, 100], a] -> Nothing;, 
   5]] // First

Which gives me 124.8 (means 124 seconds).

While the third way :

AbsoluteTiming[
  Table[Complement[Range[10^6], RandomInteger[10^6, 100]];, 
   5]] // First

just take 0.15 (means 0.15 seconds) !!

Compare those : 124 sec, 124 sec , 0.15 sec

So the best way is the third way especially for larger Lists ! :)

$\endgroup$
1
  • 3
    $\begingroup$ Complement is not guaranteed to retain the order, e.g., Complement[{4, 3, 2, 1}, {1, 3}] returns {2,4} $\endgroup$ – Roma Lee Jan 13 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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