Berk Özbalcı
Berk Özbalcı

Reputation: 3196

How to check if an element is also in another list

Imagine a function:

def Intersects (x, list1, list2, list3):
    if x in list1 and x in list2 and x in list3: return True
    return False

There has to be a better way to do this but I can't figure it out. How can I do this? (performance is important)

EDIT: I've come across a related, however harder problem this time. This time I've got 3 unrelated integers and I need to test if they intersect too.

Like:

1, 2, 3 <-- elements to look for
if InAll ((1, 2, 3)) ...

but I am not looking for a tuple, instead I am looking for just integers. How do I unpack the tuple and do the same search?

Upvotes: 1

Views: 135

Answers (3)

EnricoGiampieri
EnricoGiampieri

Reputation: 6085

The best way to do something like this is to use the set...probably it will be more efficient even with the conversion time:

def InAll(element_list, *sets):
    #calculate the intersection between all the sets
    intersection = reduce( lambda i , j: i & j, sets )
    #check if every element is in the intersection
   return all( i in intersection for i in element_list )


sets = [ set(range(5)), set(range(10)) ]
InAll( [9], *sets )
#False

sets = [ set(range(5)), set(range(10)) ]
InAll( [1,3], *sets )
#True

It's better to convert the list into set beforehand, but it's easy to insert the conversion conde inside the function (but if you have a lot of these controls, keep a copy of the set)

Upvotes: 0

Joran Beasley
Joran Beasley

Reputation: 113940

 def intersects(x,L1,L2,L3):
     if not isinstance(x,(list,tuple)):
            x = [x]
     return set(x).intersection(L1).intersection(L2).intersection(L3) == set(x)

should work for lots of stuff

>>> l1 = range(10)
>>> l2 = range(5,10)
>>> l3 = range(2,7)
>>> def intersects(x,L1,L2,L3):
...      if not isinstance(x,(list,tuple)):
...             x = [x]
...      return set(x).intersection(L1).intersection(L2).intersection(L3) == set(x)
...
>>> intersects(6,l1,l2,l3)
True
>>> intersects((5,6),l1,l2,l3)
True
>>> intersects((5,6,7),l1,l2,l3)
False

Upvotes: 0

David Robinson
David Robinson

Reputation: 78590

If you want to be able to give it any number of lists (not just three), you might like:

def inAll(x, *lsts):
    return all((x in l) for l in lsts)

If you are checking memberships in these lists many times (on many xs, that is), you'll want to make each into a set before you start looping through the xs.

From your most recent edit, it looks like you also want to be able to pass multiple items in x. Code for that would be:

def inAll(xs, *lsts):
    return all(all(x in l for x in xs) for l in lsts)

Upvotes: 9

Related Questions