Filter List of Tuples to Exclude from Another List of Tuples which Contains

Tags: , , ,

(Using Python3)

I have a list of tuples, (of strings)

have = [
 ('a', 'b', 'c', 'd'), ('a', 'b', 'c', 'e'), ('a', 'b', 'c', 'f'), ('a', 'b', 'c', 'g'), ('a', 'b', 'd', 'e'),
 ('a', 'b', 'd', 'f'), ('a', 'b', 'd', 'g'), ('a', 'b', 'e', 'f'), ('a', 'b', 'e', 'g'), ('a', 'b', 'f', 'g'),
 ('a', 'c', 'd', 'e'), ('a', 'c', 'd', 'f'), ('a', 'c', 'd', 'g'), ('a', 'c', 'e', 'f'), ('a', 'c', 'e', 'g'),
 ('a', 'c', 'f', 'g'), ('a', 'd', 'e', 'f'), ('a', 'd', 'e', 'g'), ('a', 'd', 'f', 'g'), ('a', 'e', 'f', 'g'),
 ('b', 'c', 'd', 'e'), ('b', 'c', 'd', 'f'), ('b', 'c', 'd', 'g'), ('b', 'c', 'e', 'f'), ('b', 'c', 'e', 'g'),
 ('b', 'c', 'f', 'g'), ('b', 'd', 'e', 'f'), ('b', 'd', 'e', 'g'), ('b', 'd', 'f', 'g'), ('b', 'e', 'f', 'g'),
 ('c', 'd', 'e', 'f'), ('c', 'd', 'e', 'g'), ('c', 'd', 'f', 'g'), ('c', 'e', 'f', 'g'), ('d', 'e', 'f', 'g')

I also have a list of tuples (also strings) which I want to “exclude”

 exclude = [('a', 'd'), ('b', 'c')]

I’m trying to find an efficient way to remove any element in have that contains both the elements in each exclude tuple. Ordering does not matter.

My goal is to return something like this:

 ('a', 'b', 'e', 'f'), ('a', 'b', 'e', 'g'), ('a', 'b', 'f', 'g'), ('a', 'c', 'e', 'f'), ('a', 'c', 'e', 'g'),
 ('a', 'c', 'f', 'g'), ('a', 'e', 'f', 'g'), ('b', 'd', 'e', 'f'), ('b', 'd', 'e', 'g'), ('b', 'd', 'f', 'g'), 
 ('b', 'e', 'f', 'g'), ('c', 'd', 'e', 'f'), ('c', 'd', 'e', 'g'), ('c', 'd', 'f', 'g'), ('c', 'e', 'f', 'g'), 
 ('d', 'e', 'f', 'g')


You could convert the exclude tuples to sets and then check for each element of have is the excluded set isn’t a subset of it:

excludeSet = [set(e) for e in exclude]
filteredHave = [h for h in have if not any(e for e in excludeSet if e.issubset(h))]

Source: stackoverflow