2

I have a list containing synonyms for the word 'Good' (this list here is shortened)

good_synonym = ['Good','good','Well','well']

And the program asks how the user is feeling

print = 'Hello, ' + name + ', How are you?'
status = raw_input('')

But sometimes, the user may respond to the question with "I am good" (or similar)

If the answer contains a word in the good synonym list, I want the program to reply

if status contains a word in good_synonym:
    print ('That is good')
else:
    print ('That is not so good')

note that the first line is not real python language

But I don't know which phrase to use to do the action.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Harvey Fletcher
  • 1,167
  • 1
  • 9
  • 22

5 Answers5

8

Instead of a list with mixed-case words, use set objects; sets make membership testing and intersection testing much easier. Store lowercase text only, and simply lowercase the input string:

good_synonym = {'good', 'well'}
# good_synonym = set(['good', 'well'])  # Python 2.6

Now test if the input string, lowercased and split on whitespace, is a disjoint set with set.isdisjoint(). If it is not a disjoint set, there is overlap between the two sets and that means at least 'good' or 'well' is present:

if not good_synonym.isdisjoint(status.lower().split()):
    print ('That is good')
else:
    print ('That is not so good')

Testing if a set is disjoint is efficient; it only has to test words up to the first one that is in the good_synonym set to return False quickly. You could calculate the intersection instead, but that would always test all words in the status to build a new set object.

Other solutions you may have seen, use the any() function; given a generator expression it too can be efficient as it would return True early if any of the outputs is true:

if any(word in good_synonym for word in status.lower().split()):

This, however, does all the looping and testing in Python code, while set.isdisjoint() is implemented entirely in C code.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • This question will almost pass as a dupe, but this is a clearly different perspective for handling a case as this. Dang! +1 – Moses Koledoye Sep 28 '16 at 08:59
  • I seem to keep getting a syntax error with the separator between words in the set. – Harvey Fletcher Sep 28 '16 at 09:04
  • @HarveyFletcher: are you using Python 2.6 perhaps? Then use `set(['good', 'well'])` to create a set. The curly-brace literal syntax for sets was not introduced until Python 2.7 and 3. – Martijn Pieters Sep 28 '16 at 09:16
2

There are many ways you could try to do this. Since you are a beginner, let's just go for something that will work - efficiency should NOT be your first consideration.

status = status.split() # breaks response into words
if any(s in good_synonyms for s in status):
    print('That is good')

Of course it won't stop your program from acting as though "not good" is a reply deserving a happy answer, but this is a programming site.

holdenweb
  • 33,305
  • 7
  • 57
  • 77
0

Simple!

We can iterate over the good_synonyms list and check if any of them are present in the input string.

if any(synonym in status for synonym in good_synonyms):
    print('That is good')
else:
    print('That is not so good')

PS: To save memory, you could perhaps store the synonyms only in lower-case, as ['good', 'well'], and when you check if these are in the 'status' variable, you could just apply the .lower() on it, which just converts the entire string into lower-case, as:

good_synonyms = ['good', 'well']
if any(synonym in status.lower() for synonym in good_synonyms):
     print('That is good')

Hope this helps!

Note: holdenweb's answer works too, but applying the split function on status isn't really required as you can check whether a word is present in a string(provided the words in the string are separated by a space) or not using the 'in' keyword as described above.

-1

This is a NLP question, the following code is a simple version of detecting synonym:

def is_contains_synonym(sentence, synonym):
    token = sentence.split(' ')
    return len(filter(lambda x: x in synonym, token)) > 0

if is_contains_synonym(status, good_synonym):
    print ('That is good')
else:
    print ('That is not so good')
Enix
  • 4,415
  • 1
  • 24
  • 37
-1

A short and simple solution would be to use regular expressions for pattern matching like this:

import re

line = "it is good"
good_synonyms = ["good","well"]

line = line.lower()
if any(re.search(synonym,line) for synonym in good_synonyms):
    print "That is good"
else:
    print "nope"

The search function of re looks for a match of pattern anywhere in the string and returns a boolean which then can be used in an if statement with any

Bertramp
  • 376
  • 1
  • 15