How to check if all of the following items are in a list?

Question:

I found, that there is related question, about how to find if at least one item exists in a list:
How to check if one of the following items is in a list?

But what is the best and pythonic way to find whether all items exists in a list?

Searching through the docs I found this solution:

>>> l = ['a', 'b', 'c']
>>> set(['a', 'b']) <= set(l)
True
>>> set(['a', 'x']) <= set(l)
False

Other solution would be this:

>>> l = ['a', 'b', 'c']
>>> all(x in l for x in ['a', 'b'])
True
>>> all(x in l for x in ['a', 'x'])
False

But here you must do more typing.

Is there any other solutions?

Asked By: sirex

||

Answers:

I would probably use set in the following manner :

set(l).issuperset(set(['a','b'])) 

or the other way round :

set(['a','b']).issubset(set(l)) 

I find it a bit more readable, but it may be over-kill. Sets are particularly useful to compute union/intersection/differences between collections, but it may not be the best option in this situation …

Answered By: tsimbalar

Operators like <= in Python are generally not overriden to mean something significantly different than “less than or equal to”. It’s unusual for the standard library does this–it smells like legacy API to me.

Use the equivalent and more clearly-named method, set.issubset. Note that you don’t need to convert the argument to a set; it’ll do that for you if needed.

set(['a', 'b']).issubset(['a', 'b', 'c'])
Answered By: Glenn Maynard

I like these two because they seem the most logical, the latter being shorter and probably fastest (shown here using set literal syntax which has been backported to Python 2.7):

all(x in {'a', 'b', 'c'} for x in ['a', 'b'])
#   or
{'a', 'b'}.issubset({'a', 'b', 'c'})
Answered By: martineau

What if your lists contain duplicates like this:

v1 = ['s', 'h', 'e', 'e', 'p']
v2 = ['s', 's', 'h']

Sets do not contain duplicates. So, the following line returns True.

set(v2).issubset(v1)

To count for duplicates, you can use the code:

v1 = sorted(v1)
v2 = sorted(v2)


def is_subseq(v2, v1):
    """Check whether v2 is a subsequence of v1."""
    it = iter(v1)
    return all(c in it for c in v2) 

So, the following line returns False.

is_subseq(v2, v1)
Answered By: Max

Short syntax

I discovered a very readable syntax while experimenting on the Python interpreter.

>>> my_list = [1, 2, 3, 4, 5]
>>> (6 or 7) in my_list
False
>>> (2 or 6) in my_list
True
>>> (2 and 6) in my_list
False
>>> (2 and 5) in my_list
True

List of items to search for

If you have a long list of objects to search for, held in a sub_list variable:

>>> my_list = [1, 2, 3, 4, 5]
>>> sub_list = ['x', 'y']

If any (at least one) item is contained in the superset (or statement):

>>> next((True for item in sub_list if next((True for x in my_list if x == item), False)), False)
False

>>> sub_list[0] = 3
>>> next((True for item in sub_list if next((True for x in my_list if x == item), False)), False)
True

If all items are contained in superset (and statement), then sub_list is a full subset. Also featuring a bit of De Morgan’s Law:

>>> next((False for item in sub_list if item not in my_list), True)
False

>>> sub_list[1] = 2
>>> next((False for item in sub_list if item not in my_list), True)
True
>>> next((True for item in sub_list if next((True for x in my_list if x == item), False)), False)
True
Answered By: Emirhan Özlen

An example of how to do this using a lambda expression would be:

issublist = lambda x, y: 0 in [_ in x for _ in y]
Answered By: Jundullah

Not OP’s case, but – for anyone who wants to assert intersection in dicts and ended up here due to poor googling (e.g. me) – you need to work with dict.items:

>>> a = {'key': 'value'}
>>> b = {'key': 'value', 'extra_key': 'extra_value'}
>>> all(item in a.items() for item in b.items())
True
>>> all(item in b.items() for item in a.items())
False

That’s because dict.items returns tuples of key/value pairs, and much like any object in Python, they’re interchangeably comparable

Answered By: Julio Cezar Silva

Another solution would be:

l = ['a', 'b', 'c']
potential_subset1 = ['a', 'b']
potential_subset2 = ['a', 'x']
print(False not in [i in l for i in potential_subset1]) # True
print(False not in [i in l for i in potential_subset2]) # False

What makes my solution great is that you can write one-liners by putting the lists inline.

Answered By: Johann Lau
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.