Parsing a Conditional statement with Python Recently I built a Usenet newsreader in Python and for that I built a keyword search which supports AND and OR functionalities (e.g., python AND django should bring up articles containing both. I defined a find function for this which takes a keyword query and a string and returns a bool signifying whether the string qualifies (i.e., for the above example, the string qualifies if it contains both 'python' and 'django').

Here's the snippet:

search = 'python AND django OR ruby AND rails'
query = search.split(' OR ')
query = [phrase.split(' AND ') for phrase in query]

def find(query, string):
    is_there = False
    for chunk in query: #OR
        chunk_qualified = False
        for word in chunk: #AND
            if word not in string:
                break
        else:
            chunk_qualified = True

        if chunk_qualified:
            is_there = True
            break

    return is_there


It works, but can I do it in a better manner (less code, more efficient)?
You can use the builtin function all() here to check phrases in a subquery are part of the string passed.

def get_sub_queries(query):
    for subquery in query.split(' OR '):
        yield subquery


def get_phrases(subquery):
    for phrase in subquery.split(' AND '):
        yield phrase


def find(query, string):
    for subquery in get_sub_queries(query):
        if all(phrase in string for phrase in get_phrases(subquery)):
            return True
    return False


Try to use better variable names(I know it's hard though :-)).

Apart from these I have broken your code into 3 functions now.


Contains logic to split queries to subqueries
Contains logic to split subquery to get phrases
Actual find() functionality


The reason behind this is that if the logic related to anyone of them changes later on then it won't complicate your search functionality and you can write separate tests for each of the three functionalities.



If you're on Python 3.3+ then use could also use yield from.