Reputation: 57
I'm running into a funny scenario with list comprehensions and strings. Here's a simplified example of the scenario:
This:
banned = ['apple', 'pear']
sentence = 'I will eat an apple'
if(not x in sentence for x in banned): print('ok')
Returns:
ok
Even though 'apple' appears in the sentence. Have I written the comprehension incorrectly? If any word in 'banned' is in 'sentence', 'ok' shouldn't print.
Upvotes: 1
Views: 1068
Reputation: 107287
The following part:
(not x in sentence for x in banned)
Is a generator expression that will be evaluated as True, regardless of whatever the content is.
If you want to check the truth value of multiple items you may want to use either any
or all
functions based on your problem.
In this case it seems that you need all()
:
banned = ['apple', 'pear']
sentence = 'I will eat an apple'
if all(x not in sentence for x in banned):
print('ok')
Also, note that the part x not in sentence
will check the membership within the entire string, not its words. That says, if one of the words within the input string is contain a word within banned
list it will return True. Like pearl
which is contain the word pear
.
One way for getting around that problem is to check the membership in splitted text or use regular expressions.
Another alternative would be using set
and intersection:
banned = {'apple', 'pear'} # use set instead of list
sentence = 'I will eat an apple'
if banned.intersection(sentence.split()):
print('ok')
As @Jean-FrançoisFabre mentioned it's better to use set.isdisjoint()
rather than set.intersection
since you just want to check the intersection.
banned = {'apple', 'pear'} # use set instead of list
sentence = 'I will eat an apple'
if not banned.isdisjoint(sentence.split()):
print('ok')
Upvotes: 3