TransWikia.com

How to Delete Elements from List1 appearing in List2?

Mathematica Asked by PeriodicProgrammer on March 13, 2021

I’m new to functional programming of Mathematica and trying to remove one list of assorted elements from another. However I only find functions working with the Index rather than the values itself:

 list1={b,a,e,f,c,d}  
 list2={f,e,c}

I can now remove list2 from list1:

 result={b,a,d}  

I already found out, that you can “abuse”

DeleteCases[list1, a] 

to remove 1 specific element from a list, but not a whole assorted list…

I would be very grateful for a simple solution to do it.
Thanks a lot for any answer!

7 Answers

Use

DeleteCases[list1, Alternatives @@ list2]

In new versions (M8.0+), DeleteCases is optimized on patterns not involving blanks, so this will be fast also for large lists. For earlier versions, this will work:

Replace[list1, Dispatch[Thread[list2 -> Sequence[]]],{1}]

being 2-3 times slower, but still very fast.

Correct answer by Leonid Shifrin on March 13, 2021

You are perhaps searching for Complement. Complement[list1, list2] results in {a, b, d}. The result is sorted though. If you are looking for an unsorted complement, DeleteCases[list1, Alternatives @@ list2] should probably work. I think there are some discussions on unsorted complements out there at google.

Answered by Yves Klett on March 13, 2021

Since Yves beat me narrowly to my first solution, here's another one using Select:

Select[list1, FreeQ[list2, #] &]
Out[2]= {b, a, d}

This does not sort your result.


You can also use Complement, which is more intuitive. Example:

Complement[list1, list2]
Out[1]= {a, b, d}

Note that this sorts your result (i.e., it is not in the same order, {b, a, d}).

Answered by rm -rf on March 13, 2021

Iff each list is internally free of duplicates you can use this very quick method:

DeleteDuplicates[#2 ~Join~ #] ~Drop~ Length[#2] &[list1, list2]

Answered by Mr.Wizard on March 13, 2021

Unsorted Complement. I think it originates from MathGroup. It accepts the SameTest option.

Options[UnsortedComplement] = {SameTest -> Automatic};
UnsortedComplement[all_, del___, opts : OptionsPattern[]] := 
  Replace[all, 
   List @@ (Rule[#, Sequence[]] & /@ Union[del, opts]), {1}];

all = RandomInteger[{0, 9}, {20}]
UnsortedComplement[all, {6, 2, 8}, {2, 3, 4}]

(*
  ==> {8, 4, 2, 5, 8, 8, 6, 6, 2, 1, 3, 1, 1, 2, 8, 0, 5, 5, 8, 1}

  ==> {5, 1, 1, 1, 0, 5, 5, 1}
*)

It also works with any head, not just List-s.

Answered by István Zachar on March 13, 2021

Just nest it:

Fold[DeleteCases[#1, #2] &, list1, list2]

Answered by Fortsaint on March 13, 2021

I hesitate to add to this old discussion after these excellent answers and other essential reading especially here, but this amalgamation of many suggestions may be of interest. cutEverything[xx_, removeList__] removes all entries of all elements of removeList_ from xx_ regardless of their depth or whether they are duplicates. It leaves compounds in place and does not change the original list order.

x = 
  {pudepied, pudepied.txt, {pudepied}, {{{pudepied}}, {zap}, {{peter}}}, {{pudepied}}, 
   blah, zap, "Wolfram Language", {peter}, {{{}}}, mary, {{{{mary}}}}};

remove = {pudepied, peter, mary, {}};
cutEverything[xx_, removeList_] := 
  Replace[xx, x_List :> DeleteCases[x, Alternatives @@ removeList], {0, Infinity}]
cutEverything[x, remove]
 {pudepied.txt, {{zap}}, blah, zap, Wolfram Language}

Answered by pudepied on March 13, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP