Complement

In the cell below we get all elements that are in (lst1) but not in (lst2) or (lst3).  Of course this would work with lists of arbitrary expressions, not only numbers.

lst1 = {3, 2, 7, 5, 2, 2, 3, 4, 5, 6, 1} ; lst2 = {2, 3} ; lst3 = {4, 6, 27, 23} ; Complement[lst1, lst2, lst3]

{1, 5, 7}

In the cell above Complement gives a sorted list of all elements of (lst1), that are not in (lst2).  If you want to do this without having the result sorted, DeleteCases should be used as in the next line.

DeleteCases[lst1, Alternatives @@ Union[lst2, lst3]]

{7, 5, 5, 1}

In the previous example (Alternatives@@Union[lst2, lst3]) evaluates to (2 | 3 | 4 | 27 | 23).

Complement has the option SameTest with the default setting (SameTest→Automatic).  It seems when the setting (SameTest→Automatic) is used numeric values are compared using criteria equivalent to the built-in SameQ function. Notice in the next example 45 is not in the output because it is in (lst1) and (lst2). However, 164 is in the output and this is apparently because SameQ[164,164.0] returns False.

lst1 = {12, 45, 67, 144, 164} ; lst2 = {13, 65, 88, 45, 90, 164.} ; Complement[lst1, lst2, SameTestSameQ]

{12, 67, 144, 164}

In the next example the SameTest option is used to change the criteria for when to items should be considered "the same".  Here we get a list of numbers in (lst1) such that an element of (lst1) is discarded if an element of (lst2) differs from it by less than 0.2.

Complement[lst1, lst2, SameTest (Abs[#1 - #2] <0.2&)]

{12, 67, 144}

Complement can work with expressions that have a head other than List. I demonstrate this point with Complement in the next cell.          

ClearAll[h] ; lst1 = h[3, 2, 7, 5, 2, 2, 3, 4, 5, 6, 1] ; lst2 = h[2, 3] ; lst3 = h[4, 6, 27, 23] ; Complement[lst1, lst2, lst3]

h[1, 5, 7]


Created by Mathematica  (May 16, 2004)

Back to Ted’s Tricks index page