Break and Continue
Learning Objectives
At the end of this sub-unit, students should
- appreaciate the way to minimize computation by stopping loop prematurely.
- understand the behavior of
break
.
Preliminary
Before continuing, you should ensure that you understand how loop behaves because we will be expanding on the concept. If you are not familiar with loop or how to trace loop, you may want to revisit the previous unit first.
Up To n Repetitions
There are cases where we may want to exit a loop before \(n\) repetitions. However, we want the worst-case to still be \(n\) repetition. This usually happens when we found either a solution or a counter-example to our problem. Consider the case of checking if a number is prime or composite.
Prime Number
A number \(n \geq 2\) is a prime number if \(n\) is not a product of two smaller natural numbers.
Even if we assume that \(n \geq 2\), this definition is rather hard to work with. So the first step in trying to solve this is to try to come up with an equivalent definition that is more computational. The keyword here is product. If we look at the inverse of a product, we can rephrase the definition as follows.
A number \(n \geq 2\) is a prime number if \(n\) is not divisible by numbers between 2 and \(n - 1\).
This is something we can deal with because we can have a loop that basically enumerate the values between 2 and \(n - 1\).
In other words, we start from i = 3
and we stop when i == n
.
Since we are interested in the condition to keep the loop going, the condition is actually i < n
.
But here is the interesting thing, if we find that n
is divisible by i
, we actually have a counter-example.
So the number n
is not a prime, but a composite number.
The solution to this is to first assume that n
is a prime number and if we have a counter-example, then we are sure that n
is not a prime.
Prime
Note the curious property about this loop-body.
The variable is_prime
is only ever re-assigned to False
.
Although it may be re-assigned to False
multiple times, we only ever actually need to do this once.
So what can we do?
Another attempt is to use is_prime
as part of the loop-condition.
Prime
Luckily, this condition is simple.
But there may be other conditions that are harder to be incorporated into the loop-condition.
Is there a more generic way?
There is a special keyword that can only ever be used inside a loop called break
.
When this keyword is encountered, the code will exit the nearest loop.
Using this new keyword, we can rewrite the code as follows.
Prime
This is the form of a loop that will repeat the loop-body \(n\) times at the worst-case. However, under some circumstances, the loop may be shorter than \(n\) repetition.
Bad Practice
Unfortunately for us the else
keyword can actually be attached to a loop.
The following code is accepted in Python and is actually correct!
The interesting thing is that at Line 8, the indentation level of the else
keyword is actually the same as while
keyword at Line 3.
This means that the else
keyword is actually attached to the while
at Line 3 instead of if
at Line 5.
The behavior of this else
is that it is executed only when the loop terminates normally.
By normal termination, it means that we terminate not because of a break
.
However, it is generally a bad practice to use else
on loop because a slight indentation mistake will cause the code to be wildly wrong.
The error is even very hard to detect. If we randomly check the output, we will see that all values of \(n \geq 3\) will produce the correct result. The only problem is when \(n = 2\).
Nearest Loop
To determine the nearest loop, we need to keep going up the lines. However, there are some rules we need to obey.
- We need to be sure that the
break
keyword is indeed inside the loop. - As we go up the lines, we can go out into the outer block (i.e., we go into blocks with fewer indentation level).
- We cannot go into another inner block. But this inner block is computed from the line directly below it.
The combination of the second and third rule means that the indentation level decrease but never increase.
Let us illustrate this with an example.
Consider the code below.
Think carefully about which is the nearest loop from the break
keyword.
Then check if your answer is correct.
Note that we can only jump out of the nearest loop.
This means that we cannot jump out of multiple loops.
In the example above, note that the nearest loop is still within an outer loop.
However, the location of the break
statement prevents us from even jumping out of this outer loop.
To do that, we need to have an additional break
statement such that while cond2:
is the nearest loop.
We will illustrate the behavior of break
with a simple code.
Try to trace the execution with a trace table, guess the output, and check if your understanding is correct.
Outer Iter | Inner Iter | i2 | j4 | j == 3 | print(i, j) |
---|---|---|---|---|---|
1 | 1 | 0 | 0 | False | 0 0 |
1 | 2 | 0 | 1 | False | 0 1 |
1 | 3 | 0 | 2 | False | 0 2 |
1 | 4 | 0 | 3 | True | |
2 | 1 | 1 | 1 | False | 1 1 |
2 | 2 | 1 | 2 | False | 1 2 |
2 | 3 | 1 | 3 | True | |
3 | 1 | 2 | 2 | False | 2 2 |
3 | 2 | 2 | 3 | True | |
4 | 3 | 3 | 3 | True | |
5 | 1 | 4 | 4 | False | 4 4 |
Continue
Optional Knowledge
There is the "dual" of break
that can also only be used in a loop called continue
.
Unlike break
, the keyword continue
will actually let us jump back to the beginning of the loop (i.e., the loop-condition).
This will bypass the rest of the code in the loop-body.