Why does my while loop output an out-of-bounds value?
Question:
So I was doing while loops and I noticed something strange.
count = 0
while count <= 5:
count += 1
print(count)
output:
1
2
3
4
5
6
it’s not that I don’t understand while loops. It’s that how come the count is printed up to six? when it’s supposed to print count
only if count
is less than or equal to 5?
and well 6 is beyond 5. why is this?
I know I could do
count = 0
while count != 5:
count += 1
print(count)
but I just want to understand why does putting <=
behave in an odd way?
Answers:
There is nothing odd about <=
; your loop condition allows for numbers up to and including 5
. But you increment count
and then print it, so you will print 6
last.
That’s because count = 5
satisfies your loop condition, then you add one to make it 6
and print. The next time through the loop count <= 5
is no longer true and only then loop ends.
So your code does this:
count = 0
, count <= 5
-> True
, count += 1
makes count = 1
, print 1
.
count = 1
, count <= 5
-> True
, count += 1
makes count = 2
, print 2
.
count = 2
, count <= 5
-> True
, count += 1
makes count = 3
, print 3
.
count = 3
, count <= 5
-> True
, count += 1
makes count = 4
, print 4
.
count = 4
, count <= 5
-> True
, count += 1
makes count = 5
, print 5
.
count = 5
, count <= 5
-> True
, count += 1
makes count = 6
, print 6
.
count = 6
, count <= 5
-> False
, end the loop.
You could increment the counter after printing:
while count <= 5:
print(count)
count += 1
or you could use <
to only allow numbers smaller than 5
:
while count < 5:
count += 1
print(count)
It is simple when count equals five you add 1 and it becomes 6 then it is printed and you exit the loop.
Your problem is not about how <=
works.
You are adding 1 to count
before printing it, so when count is equal to 5, you then add 1 and therefore print 6.
Let’s walk through the code and see what’s happening.
Note: If your code is doing something that you didn’t expect it to do, this is a good practice to follow.
count = 0
while count <= 5:
count += 1
print(count)
The count
starts at 0
count = 0
while count <= 5: # count = 0. Is 0 <= 5? Yes. Run the code.
count += 1
print(count)
Increment the count so it now equals 1. Print it.
while count <= 5: # count = 1. Is 1 <= 5? Yes. Run the code.
count += 1
print(count)
Increment. Print. Repeat.
Let’s move on to the interesting case that’s causing the problem.
while count <= 5: # count = 5. Is 5 <= 5? Yes. Run the code.
count += 1
print(count)
In this case the count
still satisfies the inequality, so the code runs.
What happens?
The count
, which is 5, is incremented and thus prints out 6.
Now that I hope you understand why the problem exists, let’s explore alternatives and their advantages, disadvantages, and outputs.
Let’s start with your code.
count = 0
while count <= 5:
count += 1
print(count)
Advantages: Does not print out 0
Disadvantages: Prints out 6
What if we removed the =
sign?
count = 0
while count < 5:
count += 1
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want
Disadvantages: You have to start at 0 instead of 1
What if we did as you suggested and replaced the <
sign with the !
sign?
count = 0
while count != 5:
count += 1
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want
Disadvantages: Fragile. If you ever changed your increment so that it increased by a number like, say, 3, the end point would be skipped over accidentally and the code would continue to run forever. Better to use an inequality
What if we wanted where we start to be the first number that is displayed? Well, to do this we’d have to print out the current number before we change it, so that means we have to flip the order of the events.
count = 1 # Change the first number so it's what we want displayed first.
while count <= 5:
print(count)
count += 1
Output:
1
2
3
4
5
Advantages: Does what you want and starts on the first displayed number instead of below it.
Disadvantages: If you want to stick with while
loops, this is the way to go, but there is a better way in this case.
In situations like this, where you increment numbers and then perform operations with them, it’s much more logical to just use a for
loop, which was designed for instances just like this one.
for count in range(1,5):
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want, easier to read, easier to write, less likely to cause bugs based on placement.
Disadvantages: The upper boundary must be known, unlike in a while
loop.
To make things clear i will show the two scenarios with concrete explanation:
a=0
while (a<4):
a=a+1
print(a)
output would be 1,2,3,4
Variable a=0 should satisfy the condition(a<4) of while loop to continue the execution.
a=a+1 is calculated and saved in memory of the loop which is now 1.
Therefore the number 1 would be outputted not 0 as a result of print(a).
In order to iterate again inside the loop; the number 1(that was saved in the memory of the first loop is checked against the a<4 condition). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 2.
Then the number 2 is outputted
and is saved in the memory of the second loop and checked afterwards against the a<4). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 3.
Then the number 3 is outputted
and is saved in the memory of the third loop which is checked afterwards against the a<4). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 4.
Then the number 4 is outputted, even though the condition a<4 should be satisfied. The reason is that, i have stuck inside the loop after satisfaction of previous condition 3<4 and now after i am inside the loop, the execution of the statements is inevitable which will hold to output 4. The number 4 is now saved in the memory of the fourth loop which is checked against the a<4). Which is False, execution stop here.
This scenario would be amenable and understandable to the case of the opposite scenario
a=0
while (a<4):
print(a)
a=a+1
Output would be 0,1,2,3
Variable a=0 should satisfy the condition(a<4) of while loop to continue the execution.
First the print statement is executed, and the first value coined by a in the memory of the first loop is 0. Therefore 0 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which will change to be 1 and not 0.
In order to iterate again inside the loop; the number 1(that was saved in the memory of the first loop is checked against the a<4 condition). Which is True; continue execution as previous.
The print statement is executed, and the value coined by a in the memory of the second loop is now 1. Therefore 1 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 2.
In order to iterate again inside the loop; the number 2(that was saved in the memory of the second loop is checked against the a<4 condition). Which is True; continue execution as previous.
The print statement is executed, and the value coined by a in the memory of the third loop is now 2. Therefore 2 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 3.
In order to iterate again inside the loop; the number 3(that was saved in the memory of the third loop is checked against the a<4 condition). Which is True; continue execution as previous.
First the print statement is executed, and the value coined by a in the memory of the fourth loop is now 3. Therefore 3 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 4.
In order to iterate again inside the loop; the number 4(that was saved in the memory of the fourth loop is checked against the a<4 condition). Which is False; execution stops.
For completeness:
Many beginners have difficulty with this problem conceptually. They often expect the loop to exit as soon as the condition is met, even in the middle of an iteration.
It does not work that way. The while
loop condition is only checked at the beginning of each loop. It is the same as how an if
block works – if the condition is met at the beginning, the rest of the block will be run, even if the condition stops being met.
If you want to exit a loop partway through an iteration, break
can do that. However, you need to check the condition again in order for it to matter. Also keep in mind that you are writing a condition to leave the loop, rather than a condition to stay; so the logic needs to be reversed.
A lot of the time, it is easier to write code logic that checks a condition only partway through, and use an unconditional loop. That looks like (admittedly this is a silly example):
while True:
count += 1
if count > 5:
break
print(count)
In Python 3.8 and above, it is sometimes possible to simplify that sort of code using the so-called "walrus" operator, which assigns a value but also creates an expression rather than a statement (like how =
works in C and C++):
count = 0
while (count := count + 1) <= 5:
print(count)
(Note that we cannot use :+=
or +:=
to avoid repeating count
; those simply don’t exist.)
So I was doing while loops and I noticed something strange.
count = 0
while count <= 5:
count += 1
print(count)
output:
1
2
3
4
5
6
it’s not that I don’t understand while loops. It’s that how come the count is printed up to six? when it’s supposed to print count
only if count
is less than or equal to 5?
and well 6 is beyond 5. why is this?
I know I could do
count = 0
while count != 5:
count += 1
print(count)
but I just want to understand why does putting <=
behave in an odd way?
There is nothing odd about <=
; your loop condition allows for numbers up to and including 5
. But you increment count
and then print it, so you will print 6
last.
That’s because count = 5
satisfies your loop condition, then you add one to make it 6
and print. The next time through the loop count <= 5
is no longer true and only then loop ends.
So your code does this:
count = 0
,count <= 5
->True
,count += 1
makescount = 1
, print1
.count = 1
,count <= 5
->True
,count += 1
makescount = 2
, print2
.count = 2
,count <= 5
->True
,count += 1
makescount = 3
, print3
.count = 3
,count <= 5
->True
,count += 1
makescount = 4
, print4
.count = 4
,count <= 5
->True
,count += 1
makescount = 5
, print5
.count = 5
,count <= 5
->True
,count += 1
makescount = 6
, print6
.count = 6
,count <= 5
->False
, end the loop.
You could increment the counter after printing:
while count <= 5:
print(count)
count += 1
or you could use <
to only allow numbers smaller than 5
:
while count < 5:
count += 1
print(count)
It is simple when count equals five you add 1 and it becomes 6 then it is printed and you exit the loop.
Your problem is not about how <=
works.
You are adding 1 to count
before printing it, so when count is equal to 5, you then add 1 and therefore print 6.
Let’s walk through the code and see what’s happening.
Note: If your code is doing something that you didn’t expect it to do, this is a good practice to follow.
count = 0
while count <= 5:
count += 1
print(count)
The count
starts at 0
count = 0
while count <= 5: # count = 0. Is 0 <= 5? Yes. Run the code.
count += 1
print(count)
Increment the count so it now equals 1. Print it.
while count <= 5: # count = 1. Is 1 <= 5? Yes. Run the code.
count += 1
print(count)
Increment. Print. Repeat.
Let’s move on to the interesting case that’s causing the problem.
while count <= 5: # count = 5. Is 5 <= 5? Yes. Run the code.
count += 1
print(count)
In this case the count
still satisfies the inequality, so the code runs.
What happens?
The count
, which is 5, is incremented and thus prints out 6.
Now that I hope you understand why the problem exists, let’s explore alternatives and their advantages, disadvantages, and outputs.
Let’s start with your code.
count = 0
while count <= 5:
count += 1
print(count)
Advantages: Does not print out 0
Disadvantages: Prints out 6
What if we removed the =
sign?
count = 0
while count < 5:
count += 1
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want
Disadvantages: You have to start at 0 instead of 1
What if we did as you suggested and replaced the <
sign with the !
sign?
count = 0
while count != 5:
count += 1
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want
Disadvantages: Fragile. If you ever changed your increment so that it increased by a number like, say, 3, the end point would be skipped over accidentally and the code would continue to run forever. Better to use an inequality
What if we wanted where we start to be the first number that is displayed? Well, to do this we’d have to print out the current number before we change it, so that means we have to flip the order of the events.
count = 1 # Change the first number so it's what we want displayed first.
while count <= 5:
print(count)
count += 1
Output:
1
2
3
4
5
Advantages: Does what you want and starts on the first displayed number instead of below it.
Disadvantages: If you want to stick with while
loops, this is the way to go, but there is a better way in this case.
In situations like this, where you increment numbers and then perform operations with them, it’s much more logical to just use a for
loop, which was designed for instances just like this one.
for count in range(1,5):
print(count)
Output:
1
2
3
4
5
Advantages: Does what you want, easier to read, easier to write, less likely to cause bugs based on placement.
Disadvantages: The upper boundary must be known, unlike in a while
loop.
To make things clear i will show the two scenarios with concrete explanation:
a=0
while (a<4):
a=a+1
print(a)
output would be 1,2,3,4
Variable a=0 should satisfy the condition(a<4) of while loop to continue the execution.
a=a+1 is calculated and saved in memory of the loop which is now 1.
Therefore the number 1 would be outputted not 0 as a result of print(a).
In order to iterate again inside the loop; the number 1(that was saved in the memory of the first loop is checked against the a<4 condition). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 2.
Then the number 2 is outputted
and is saved in the memory of the second loop and checked afterwards against the a<4). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 3.
Then the number 3 is outputted
and is saved in the memory of the third loop which is checked afterwards against the a<4). Which is True; continue execution as previous.
a=a+1 calculated and saved in memory of loop which is now 4.
Then the number 4 is outputted, even though the condition a<4 should be satisfied. The reason is that, i have stuck inside the loop after satisfaction of previous condition 3<4 and now after i am inside the loop, the execution of the statements is inevitable which will hold to output 4. The number 4 is now saved in the memory of the fourth loop which is checked against the a<4). Which is False, execution stop here.
This scenario would be amenable and understandable to the case of the opposite scenario
a=0
while (a<4):
print(a)
a=a+1
Output would be 0,1,2,3
Variable a=0 should satisfy the condition(a<4) of while loop to continue the execution.
First the print statement is executed, and the first value coined by a in the memory of the first loop is 0. Therefore 0 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which will change to be 1 and not 0.
In order to iterate again inside the loop; the number 1(that was saved in the memory of the first loop is checked against the a<4 condition). Which is True; continue execution as previous.
The print statement is executed, and the value coined by a in the memory of the second loop is now 1. Therefore 1 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 2.
In order to iterate again inside the loop; the number 2(that was saved in the memory of the second loop is checked against the a<4 condition). Which is True; continue execution as previous.
The print statement is executed, and the value coined by a in the memory of the third loop is now 2. Therefore 2 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 3.
In order to iterate again inside the loop; the number 3(that was saved in the memory of the third loop is checked against the a<4 condition). Which is True; continue execution as previous.
First the print statement is executed, and the value coined by a in the memory of the fourth loop is now 3. Therefore 3 is outputted.
Afterwards a=a+1 is calculated and saved in memory of the loop which is now 4.
In order to iterate again inside the loop; the number 4(that was saved in the memory of the fourth loop is checked against the a<4 condition). Which is False; execution stops.
For completeness:
Many beginners have difficulty with this problem conceptually. They often expect the loop to exit as soon as the condition is met, even in the middle of an iteration.
It does not work that way. The while
loop condition is only checked at the beginning of each loop. It is the same as how an if
block works – if the condition is met at the beginning, the rest of the block will be run, even if the condition stops being met.
If you want to exit a loop partway through an iteration, break
can do that. However, you need to check the condition again in order for it to matter. Also keep in mind that you are writing a condition to leave the loop, rather than a condition to stay; so the logic needs to be reversed.
A lot of the time, it is easier to write code logic that checks a condition only partway through, and use an unconditional loop. That looks like (admittedly this is a silly example):
while True:
count += 1
if count > 5:
break
print(count)
In Python 3.8 and above, it is sometimes possible to simplify that sort of code using the so-called "walrus" operator, which assigns a value but also creates an expression rather than a statement (like how =
works in C and C++):
count = 0
while (count := count + 1) <= 5:
print(count)
(Note that we cannot use :+=
or +:=
to avoid repeating count
; those simply don’t exist.)