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.

3
  • What have you tried? Have you looked for info before asking? Commented Sep 28, 2016 at 8:53
  • I looked around and found many references to an "any()" command but I don't fully understand its usage. Commented Sep 28, 2016 at 8:54
  • this question is barely the same as yours: stackoverflow.com/questions/5319922/… Commented Sep 28, 2016 at 8:55

5 Answers 5

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.

Sign up to request clarification or add additional context in comments.

3 Comments

This question will almost pass as a dupe, but this is a clearly different perspective for handling a case as this. Dang! +1
I seem to keep getting a syntax error with the separator between words in the set.
@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.
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.

5 Comments

Also note @martijn's comments about using sets and preferring lower case.
Efficiency can be reached simply by using a set or a frozenset instead of a list for good_synonyms.
When you are learning, no new complication should be regarded as "simple" so I chose to focus on the essentials
I agree, but it's important to give the way to improvement. Learning is not the end. That's why i write a comment, rather than editing your answer.
We are both working to the same end. Thanks for the note.
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.

Comments

-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

Comments

-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')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.