Reputation: 37
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
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
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
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
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