GP89
GP89

Reputation: 6730

Python, removing whole list if it contains a matching tuple

I hope this hasn't been asked before but it's hard for me to put into words what it is I'm trying to do!

It might be easier if I explain my input, and desired output

l1 = [[(14, 'h'), (14, 'd')], [(14, 'h'), (14, 'c')], [(14, 'h'), (14, 's')], [(14, 'd'), (14, 'c')], [(14, 'd'), (14, 's')], [(14, 'c'), (14, 's')], [(13, 'h'), (13, 'd')], [(13, 'h'), (13, 'c')], [(13, 'h'), (13, 's')], [(13, 'd'), (13,'c')], [(13, 'd'), (13, 's')], [(13, 'c'), (13, 's')], [(12, 'h'), (12, 'd')], [(12, 'h'), (12, 'c')], [(12, 'h'), (12, 's')], [(12, 'd'), (12, 'c')], [(12, 'd'), (12, 's')], [(12, 'c'), (12, 's')]]

l2 = [(13,'h'),(13,'d'),(14,'c'),(14,'s'),(14,'h')]

So this first list, l1, is a list of lists, each list is a poker hand of 2 cards.

Basically what I'm trying to do is if a card is in l2, the hand in l1 needs to be removed. So the entry [(14,'d'),(14,'c')] needs to be removed from l1 because (14,'c') is in l2-- even though (14,'d') isn't in l2.

The desired output from this example should be,

[[(13, 'c'), (13, 's')], [(12, 'h'), (12, 'd')], [(12, 'h'), (12, 'c')], [(12, 'h'), (12, 's')], [(12, 'd'), (12, 'c')], [(12, 'd'), (12, 's')], [(12, 'c'), (12, 's')]]

I thought about iterating over all the tuples inside l1 and removing them if they're in l2, then afterwards go back and iterate over the lists in l1 and remove any without len == 2. This doesn't seem like the best way to go, though.

Any thoughts?

ManyTIA!

Upvotes: 2

Views: 229

Answers (3)

Ignacio Vazquez-Abrams
Ignacio Vazquez-Abrams

Reputation: 799110

[x for x in l1 if not any(y in l2 for y in x)]

Upvotes: 1

Marco Mariani
Marco Mariani

Reputation: 13776

    >>> [x for x in l1 if not set(x).intersection(l2)]
[[(13, 'c'), (13, 's')], [(12, 'h'), (12, 'd')], [(12, 'h'), (12, 'c')], [(12, 'h'), (12, 's')], [(12, 'd'), (12, 'c')], [(12, 'd'), (12, 's')], [(12, 'c'), (12, 's')]]

Upvotes: 0

kennytm
kennytm

Reputation: 523514

l2_set = set(l2)
# or use 
#   l2_set = {(13,'h'),(13,'d'),(14,'c'),(14,'s'),(14,'h')}
# directly

l1 = [hand for hand in l1 if not (hand[0] in l2_set or hand[1] in l2_set)]

If the entry may contain ≥2 members, you could generalize the filter condition to

l1 = [hand for hand in l1 if all(subhand not in l2_set for subhand in hand)]

Upvotes: 5

Related Questions