views:

99

answers:

3

I found, that there is related question, about how to find if at least one item exists in a list:
http://stackoverflow.com/questions/740287/python-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 througth 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?

+3  A: 

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 ...

tsimbalar
Actually, `MySet.issubset(MyOtherSet)` and `MySet <= MyOtherSet` are the same.
wok
@wok : oh I didn't know that, but I think the <= syntax is a bit confusing as a similar syntax can be used with lists, but with a very different meaning.
tsimbalar
it's not really that confusing if you recall the inclusion defines a partial order on any set of sets. It's actually slightly confusing that `<=` has the meaning it does for sequences: one might expect it to mean 'is a subsequence` of rather than lexicographical ordering.
aaronasterling
@aaronasterling : mmm, I personnally don't think too much about "partial order" when I type code :-), but I agree on the fact that using `<=` with sequences also feels strange, somehow ...
tsimbalar
Comparison operators only defining a partial order--whether or not you know what it's called :)--are fairly unusual. I think most people intuitively expect that `!(a <= b)` implies `b <= a`, which a partial order does not--both `set([1]) <= set([2])` and `set([2]) <= set([1])` are false.
Glenn Maynard
+3  A: 

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'])
Glenn Maynard
@Glenn : didn't know you could pass the list directly as an argument to issubset ... nice !
tsimbalar
While I agree with the sentiment, I'm pretty OK with the idea of `<=` and `issubset` meaning the same thing. Why do you dislike it?
Just Some Guy
@Just: Primarily, because it's not obvious what `<=` means for a set without either looking it up in the docs or having a prior knowledge of what it means in set theory, whereas everyone knows what `issubset` means automatically.
Glenn Maynard
A: 

I like these two because they seem the most logical, the latter being shorter and probably fastest (shown here using new Set Literals which were backported to Python 2.7):

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