digitalfire
digitalfire

Reputation: 37

Unable to break from for statement in Python

I am having trouble breaking out of the for loop in the following code:

def getTakeaway():
    list = ['pizza', "italian", "chinese", "indian"]
    query = input("Please say what take away you'd like").lower()
    query_words = set(list).intersection(query.split())
    for word in query_words:
        with open('takeaway.txt') as f:
            for line in open('takeaway.txt'):
                        if word in line:
                            print (line)
                            break
    else:
        print("sorry your request could not be found")
getTakeaway()

The program should break a string and check the string against a list. If the string contains a word in the list, it opens a text file and pulls out a line which contains the word, prints the line and then it should break. My problem is the 'else' section, where I want it to return a message saying the request could not be found.

At the minute, it prints "sorry your request could not be found" even if it does find the word in the list. It should only print that out if word is not in my list.

I hope this makes sense

Thanks

Upvotes: 0

Views: 130

Answers (4)

Mike Müller
Mike Müller

Reputation: 85442

The break belongs to a different loop than the else. The else becomes active it the loop terminates without a break. While you inner loop terminates with a break, your outer loop, on which you put the else, does not.

Putting the check for the words into its own function provides a pretty readable solution:

def find_line(file_name, query_words):
    with open(file_name) as fobj:
        for line in fobj:
            for word in query_words:
                if word in line:
                    return line

line = find_line('takeaway.txt', query_words)
if line:
    print(line)
else:
    print("sorry your request could not be found")

Upvotes: 0

Robert E
Robert E

Reputation: 401

Use a function for the inner loop and move reading outside all the loops.

def TryWord(word, words):
    for line in words:
        if word in line:
            return line
    return ''

def getTakeaway():
    list = ['pizza', "italian", "chinese", "indian"]
    query = input("Please say what take away you'd like")
    query_words = set(list).intersection(query.split())
    with open('takeaway.txt') as f:
        takeaway_words = f.read().split('\n')
    line = ''
    for word in query_words:
        line = TryWord(word, takeaway_words)
        if line:
            print (line)
            break
    if not line:
        print ("sorry your request could not be found")

getTakeaway()

Upvotes: 0

QuiteClose
QuiteClose

Reputation: 686

The basic structure of your function is like so:

def example():
    for item in iterable:
       for element in other_iterable:
           if item in element:
               print(item)
               break
    else:
        print('Only seen if "for item in iterable" fails to complete')

The break here is actually breaking out of the for element in other_iterable loop. That's why your else statement isn't being caught: the for statement it's associated with completes successfully.

The easiest way to resolve this is to put the inner-loop in a function. That way, you get to use the return keyword:

def example():
    def loop_until_found(iterable, test):
       for item in iterable:
           if item in test:
               print(item)
               return True
       return False

    for item in iterable:
        if loop_until_found(other_iterable, item):
            break
    else:
        print('Only seen if "for item in iterable" fails to complete')

One last point, when you open a file using the with statement you assign it to f. That means that you don't need to open it twice:

with open('takeaway.txt') as f:
    for line in f:
        if word in line:
            print (line)
            break

Upvotes: 0

kindall
kindall

Reputation: 184161

Your break breaks out of the inner for loop. The outer for loop always completes all iterations. You'll need some way to break out of the outer for loop. Like an exception, perhaps:

try:
    for word in query_words:
        with open('takeaway.txt') as f:
            for line in open('takeaway.txt'):
                if word in line:
                    raise StopIteration
except StopIteration:
    print(line)
else:
    print("sorry your request could not be found")

Upvotes: 5

Related Questions