1

I have a python script, and I should check if two words are present in a sentence separated by dash

test_dash_sentence="wordtest-wordtest-word3-word4"

if ("word1" and "word2") or ("word1" and "word3") in test_dash_sentence:
    print("FOUND")
else:
    print("NOT FOUND")

The issue I have is that is return me "FOUND" even if word1 is not present, so it should return me "NOT FOUND"

I have tried different models (with simple quotation, without parentheses) and it seems to work if I only look for one word in the sentence, but when I look for two words, it doesn't work.

Ced
  • 1,293
  • 5
  • 23
  • 34
  • Does this answer your question? [Check if multiple strings exist in another string](https://stackoverflow.com/questions/3389574/check-if-multiple-strings-exist-in-another-string) – PM 77-1 Dec 28 '20 at 17:43
  • @PM77-1 Not entirely, because in your link, they look for a or b or c in a string, and I look for a and b `or` a and c – Ced Dec 28 '20 at 18:02

3 Answers3

3

the problem is you assume that the and and or syntax is aggrgated to the in later, but this is not true... and you if statment translated to of True in test_dash_sentence: because the statement is casting strings to boolean.. as follows:

if ("word1" and "word2") or ("word1" and "word3"):
   print(True):
else:
   print(False)
>>> True

solution:

just change:

if ("word1" and "word2") or ("word1" and "word3") in test_dash_sentence:

to:

if ("word1" in test_dash_sentence and "word2" in test_dash_sentence) or ("word1" in test_dash_sentence and "word3" in test_dash_sentence) :

EDIT: as commented by @JohnnyMopp below you can also make the statement shorter so just:

if ("word1" in test_dash_sentence) and ("word2" in test_dash_sentence or  "word3" in test_dash_sentence) :

MORE EXPLAINATION BY REQUEST

python does not support the syntax of (element1 and element2 ) in mylist, the in keyword can be only applied to one element at a time so instead you must do element1 in list and element2 in mylist, what happening is python treat (element1 and element2 ) as a separate statement, evaluates it to boolean and then check if the resulting boolean is exist in the mylist.

adir abargil
  • 5,495
  • 3
  • 19
  • 29
  • 1
    Since you have `"word1" in test_dash_sentence` twice, you can combine and make shorter. – 001 Dec 28 '20 at 17:42
  • 1
    Note that `if ("word1" and "word2") or ("word1" and "word3") in test_dash_sentence` is evaluated as `if (True and True) or ...` which evaluates as True – MYousefi Dec 28 '20 at 17:42
  • Thanks @adirabargil for the details I gave you 1 upvote, your answer solve the main issue, however I am worried applying it to large quantity of data make it really hard to read and to maintain – Ced Dec 28 '20 at 18:50
  • if you will show demonstration of how the data is expanding we can find a way the is more readable and generic, but for your current example i did my best... i think it is an appropriate answer... anyway @azro answer might answer your needs if the conditions are meeting the situation... – adir abargil Dec 28 '20 at 18:52
  • Indeed you have answered perfectly to the main problem, and quickly, I thank you for it. Also people rarely think about it, but thank you to upvote the question if it seems relevant to you. – Ced Dec 29 '20 at 10:22
  • with pleasure... if you find this answer helpful you are welcome to accept it :) – adir abargil Dec 29 '20 at 10:30
1

You must repeat in test_dash_sentence for each word, with the simplification of word1 being in both clauses, you get

if "word1" in test_dash_sentence and ("word2" in test_dash_sentence or "word3" in test_dash_sentence):

You can also use all/any

required = ['word1']         # all of them must be found
any_of = ['word2', 'word3']  # at least one of them must be found

if all(w in test_dash_sentence for w in required) and \
   any(w in test_dash_sentence for w in any_of):
    print("FOUND")
else:
    print("NOT FOUND")

For multiple possible required word having each their optionnal words (one must match), you can use a dict to store, and a 2-level any then

words = {
    'w1': ['opt1', 'opt2'],
    'w2': ['opt4', 'opt5', 'opt44', 'opt55'],
    'w3': ['opt6', 'opt7'],
}

if any(
        required in test_dash_sentence and any(w in test_dash_sentence for w in any_of)
        for required, any_of in words.items()
):
    print("FOUND")
else:
    print("NOT FOUND")
azro
  • 53,056
  • 7
  • 34
  • 70
  • Sorry, could you please explain what does `w`represent in your second part ? I find it quite confusing – Ced Dec 28 '20 at 18:10
  • @Ced that is a local function, that represent the word from the array, either `required` or `any_of`, it is used for the test `w in test_dash_sentence` – azro Dec 28 '20 at 18:11
  • Ok thanks for clarification, how would you arrange the second part, to do the same but for a lot of data, let's say for instance I have 3 required words, and each of them uniquely have their 4 optional words corresponding (all unique to their respective required words) – Ced Dec 28 '20 at 18:18
  • Thanks, but in the edit you use `required` and `any_of` while only having a `dict` called `words` so I don't see how could it works, did I miss something? – Ced Dec 28 '20 at 18:26
  • @Ced they come from `for required, any_of in words.items()` – azro Dec 28 '20 at 18:34
  • it does works but I can't fully explain why, could you please add comments and find a way to make it more beginner friendly ? for instance, I don't get how `required` takes the first `dict` level and `any_of` the second level of the `dict` – Ced Dec 28 '20 at 18:48
  • @Ced that is what `.items` works, it returns a pair of key/value (there is no **level**, just key and value) – azro Dec 29 '20 at 09:52
  • Ok but how does it know `required` refer to the key, and `any_of` to a value ? – Ced Dec 29 '20 at 10:17
  • @Ced `items()` generates pairs of key/value, so `for a,b in mydict.items()` generates the pairs, `a` as key, `b` as value – azro Dec 29 '20 at 14:17
0

your boolean condition is not correct. Also, "word1" is twice in your condition, so you can combine them:

test_dash_sentence="wordtest-wordtest-word2-word3"

if "word1" in test_dash_sentence and ("word2" in test_dash_sentence or "word3" in test_dash_sentence):
    print("FOUND")
else:
    print("NOT FOUND")
ljuk
  • 701
  • 3
  • 12
  • Thank you for your answer and welcome to StackOverflow ! don't hesitate to also upvote the question if it seems relevant to you! :) – Ced Dec 29 '20 at 10:48