5

If I have a 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.

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
Jan Eerland
  • 2,001
  • 10
  • 17

4 Answers4

8

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 ! :)

Hossein Hadi
  • 635
  • 5
  • 11
  • 3
    Complement is not guaranteed to retain the order, e.g., Complement[{4, 3, 2, 1}, {1, 3}] returns {2,4} – Roma Lee Jan 13 '21 at 19:03
2
list = {1, 2, 4, 70, 11, 20, 56, 79};

d = {2, 4, 56};

Using DeleteElements (new in 13.1)

DeleteElements[list, d]

{1, 70, 11, 20, 79}

Complement, suggested in the accepted answer, sorts the result:

Complement[list, d]

{1, 11, 20, 70, 79}

eldo
  • 67,911
  • 5
  • 60
  • 168
2
list = {1, 2, 4, 70, 11, 20, 56, 79};

d = {2, 4, 56};

Using Position and Delete:

Delete[#, Position[#, Alternatives @@ d]] &@list

({1, 70, 11, 20, 79})

Or using Pick:

Pick[#, And @@ Thread[# != d] & /@ #] &@list

({1, 70, 11, 20, 79})

E. Chan-López
  • 23,117
  • 3
  • 21
  • 44
1
vis = {2, 4, 56} // AssociationMap[True&];

{1, 2, 4, 70, 11, 20, 56, 79} // Select[!KeyExistsQ[#][vis]&]

$O(n)$ and keep the order.

AsukaMinato
  • 9,758
  • 1
  • 14
  • 40