How can we exit a loop?

Question

In the context of this code challenge, how can we exit a loop?

Answer

In Python, the main way to exit a loop is using the break statement. When the break statement runs in a loop, it will terminate that loop.

However, one thing to keep in mind is that break statements will only terminate the innermost loop that it is run inside. So if you have a nested loop, the outer loop will continue to run.

You can also exit a loop using the return statement, but only if the loop is inside of a function. Furthermore, the return statement will not only exit the loop, but will also exit the entire function, so be careful when using it.

10 Likes

This one is tricky, I’ve got the correct answer by using 1 conditional and relative return statement inside the loop and 1 with another return statement outside. So no need for break statement in this case.

did not use break either:

def over_nine_thousand(lst):
new_list = 0
for i in lst:
if new_list < 9000:
new_list += i
else:
return new_list

3 Likes

Can we solve the Lesson via ‘while’-function?

def over_nine_thousand(lst):
  sum = 0
  while sum < 9000:
    sum += lst[?]
  return sum

I can’t understand, where to put an iterator?
And generally, where is the iterator in the ‘while’-function? E.g., earlier in the Lesson “while”, how did the program understand, that it should iterate through all_students.pop() (code - below)?

all_students = ["Alex", "Briana", "Cheri", "Daniele", "Dora", "Minerva", "Alexa", "Obie", "Arius", "Loki"]
students_in_poetry = []

while len(students_in_poetry) < 6:
  students_in_poetry.append(all_students.pop())
2 Likes

There’s no iterator involved. If you are not detail-oriented, just jump to the bottom for a direct response to your query. Continue from here for more on iteration and iterators.


A bit of terminology: to a first approximation, iteration is stepping through an assemblage of data one item at a time; an iterable is a collection of data through which you can iterate; and an iterator is an object which combines (`‘packages’) an iterable with a __next__() method, allowing you to, well, iterate, by calling next().

  • A list is an iterable [1,2,3,4]
  • The for - in operator turns it into an iterator, and automatically provides the “next”. Very convenient!
  • But, you can do it yourself, by using iter():
x = [1,2,3,4]
y = iter(x)
print(y)
    
print(next(y))
print(next(y))
print(next(y))
print(next(y))
print(next(y))

*Output:

<list_iterator object at 0x02FF67D0>
1
2
3
4
Traceback (most recent call last):
  File "C:\path\to\test.py", line 9, in <module>
    print(next(y))
StopIteration

… and oh yes, the for-in operator knows what to do when StopIteration is raised!


All of the above is simply to point out that there is no iterator in a while loop. You can program a while loop to iterate. You can even use while to create an iterator; in fact, that’s basically how for loops work. … while rules!

But in its essence, a while loop simply tests for a certain condition each time around. It only iterates if you want it to. The variable that you increment might be referred to as an iteration variable, but it is not an iterator.


So what is the answer to your question?
First example: Why not begin with i = 0, then go with

sum += lst[idx]
idx += 1

each time around.

As for the second one, remember that while does not necessarily iterate, it just tests a condition. Remember what pop() does: it removes an item from the end of a list, and returns that item. So If you are popping off one of the students from a list and appending them to another list, all you need to do to get it right is decide how many students you want to move from one list to the other and put that number in the while condition (in this case, the condition is that the length of the new list is less than 6).

5 Likes

def over_nine_thousand(lst):
if (sum(lst) > 9000):
break
return sum(lst)

print(over_nine_thousand([8000, 900, 120, 5000]))

#I’m wondering why my code doesn’t work :frowning:

def over_nine_thousand(lst):
if (sum(lst) > 9000):
break
return sum(lst)

print(over_nine_thousand([8000, 900, 120, 5000]))

My indentations are correct tho’

Please show us by posting your code so that the indentations are visible. Do so by using the </> icon that is in the middle of the menu bar at the top of the text box when you open it for typing or editing.

def over_nine_thousand(lst):
  if (sum(lst) > 9000):
    break 
  return sum(lst)

print(over_nine_thousand([8000, 900, 120, 5000]))

There are two main issues with your code, as best I can tell:

  1. The break in line three. The break statement is used to exit a for or while loop, but your code has neither.

  2. Your if statement checks if the sum of the entire list is greater than 9000, rather than checking element by element.

To elaborate on the second point, with the given list [8000, 900, 120, 5000] the function should stop summing after the third element, because at that point it crosses the threshold, so the function should return 9200, but your function would return 14200 i.e. the sum of the entire list.

On a separate note, I thought it worth just mentioning that the task description could be misinterpreted i.e. I misinterpreted the task description at first:

1. Create a function named over_nine_thousand() that takes a list of numbers named lst as a parameter.

The function should sum the elements of the list until the sum is greater than 9000 . When this happens, the function should return the sum. If the sum of all of the elements is never greater than 9000 , the function should return total sum of all the elements. If the list is empty, the function should return 0 .

For example, if lst was [8000, 900, 120, 5000] , then the function should return 9020 .

Now, especially given that they used the word “never” instead of “not”, that indicates to me, that the function should continue summing the list until 9000 has been surpassed, not just until either 9000 is reached or the list ends.

So I was assuming that a list like [1000, 2000, 3000] should produce an output of 12000—i.e. once all the elements have been summed and 9000 has not been surpassed it resumes from the beginning of the list and keeps going—rather than the answer of 6000 that they were looking for.

It was only after an error message said that the list [8000, 900] would produce the result 16900 with my function, instead of the desired 8900 that it dawned on me what they actually wanted us to do.

Apologies if this is the wrong place for this type of feedback, but I wasn’t sure where else to go with it, and I think the language could do with a once over to make the task at hand a little clearer.

3 Likes
def over_nine_thousand(lst):
  total =[]
  for i in lst:
    total.append(i)                         #appending elements of i into total
    if sum(total) >= 9000:            #giving code a condition
      break                                       #breaking loop when it reaches approx. 9000
      return total                            #returning new element into total

I really thought this would work, but it returns None and I don't understand why. Can anyone help guide me in the right direction?

Thank you!

Do you know what break and return do?
If no, go read up on that
If yes, read your code
Your use of them suggests no. You may of course not have thought it through, so that’s what the “yes” option there is suggesting you do.

Alternatively, add prints in your code which write out everything that’s being done and observe. You can also use this to compare what you expected to happen.

2 Likes

I am familiar with return and break.
My idea was to break the loop and return the new list with the indicies sum to/around 9000.
I’ve been working on this code and reading different ideas on stack overflow to help guide me which might have confused my logic.

1 Like

break and return

Your return comes after break
What break does is precisely to prevent what follows from executing
If you want to return after breaking then you would need to put the return statement at the location where execution will continue after breaking, and additionally consider whether that’s also the right thing to do when execution reaches that location without breaking.

By the way, return has somewhat similar behaviour to break, so if you’re supposed to return, does it in any way help to break first?

And, in case you never break the loop, should that not also have a result? (Consider all paths your code may take)

2 Likes

Thank you.

I moved my return to outside the function and received something I was looking for, but not right for the solution. I will keep trying and work with your advice.

1 Like

Just keep in mind that you can get information out about what’s being done by printing, meaning you can verify the effect of anything you do

You can very much make your program log out each action taken. Or if you know what information you want, print out only that.

I’d hope not. What does return do again? It is only meaningful in the context of a function.

1 Like

Thank you,

I have been using print to check what I am doing. It is just that my logic is not sound yet.

def over_nine_thousand(lst):
  total =[]
  for i in lst:
    total.append(i)                     
    if sum(total) >= 9000:         
      return sum(total)    
    elif len(lst) == 0:
      return 0
    elif sum(lst) < 9000:
      return sum(lst)

I removed the break and returned what I was asking from my condition. I have received the desired output intended, but the error shows None has been returned even though on my console it shows 9020; which is what the exercise was asking for…confused

1 Like

How many times are you testing the length of lst? Does that length change?
What about its sum? Does that change?

Keep a firm idea of what is supposed to happen, if you’re not completely convinced about that then don’t type anything yet

2 Likes