Harvey Fletcher
Harvey Fletcher

Reputation: 1172

Python check if any part of string in list

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.

Upvotes: 2

Views: 5989

Answers (5)

Enix
Enix

Reputation: 4579

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

Upvotes: -1

Bertramp
Bertramp

Reputation: 385

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

Upvotes: -1

Akaash Agarwal
Akaash Agarwal

Reputation: 1

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.

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1122152

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.

Upvotes: 8

holdenweb
holdenweb

Reputation: 37033

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.

Upvotes: 2

Related Questions