[Tutor] Prime Numbers

Steven D'Aprano steve at pearwood.info
Sun Dec 15 18:20:11 CET 2013


On Sun, Dec 15, 2013 at 05:54:10PM +0100, Rafael Knuth wrote:
> Hej,
> 
> I stumbled upon this program here (Python 3.3.0) and I don't quite
> understand how the for loop plays with the return True statement:
> 
> def is_prime(number):
>     for element in range(2, number):
>         if number % element == 0:
>             return False
>     return True

Let's run through that, with number = 5.

When we reach the for-loop, we get:

    for element in range(2, 5)

which loops over [2, 3, 4] (the stop value of range doesn't get 
used). So the first time around the loop, element = 2 and we test:

    if 5 % 2 == 0

which is false. Since there is no "else" matching the "if", the if 
statement is complete. There is nothing in the loop after the "if", so 
we return to the beginning of the loop, and test:

    if 5 % 3 == 0

which is also false. Again, there is no "else" clause matching the "if", 
and nothing following the "if", so we return to the beginning of the 
loop again. Here we execute:

    if 5 % 4 == 0

which is again false, so we return to the beginning of the for-loop. 
This time there are no more values to use, so we continue just past the 
for-loop, which gives us:

    return True

and we exit the function.

Now this time let's do it again with number = 6. This one will be much 
shorter: we loop over the elements [2, 3, 4, 5], and the first time 
around the loop we test:

    6 % 2 == 0

which is true. Since it is true, we execute the body of the "if" clause, 
which is

    return False

which exits the loop and the function, and we're done.



> Now, I would expect the following in case I call the function with the
> variable 3:
> 
> number = 3
> for element in range(2, 3):
> 3 % 2 != 0:
> Loop ends and program returns True.

Correct. But the loop ends because there are no more values to get: 
range(2, 3) starts at 2 and stops *before* 3, which means you only get 
one value: [2]. So after handling 2, there are no more values to handle.


> Let's do the same with the variable 9:
> 
> number = 9
> for element in range(2,9):
> 3 % 2 != 0:
> My assumption is that the program should end the loop after the first
> iteration again and it then should return True.

No. If it did that, it wouldn't be a *loop* at all, would it? The whole 
reason loops (for and while) exist is to run the code repeatedly. If 
they only ran once, no matter what, they would be useless.

Unless you exit a loop early (with a return, a break, or by raising an 
exception) the loop will jump back to the beginning until such time as 
the loop is completed. Then it will jump to the code following the loop.

So, here's a simple example:

for element in range(5):
    print(element)


With your assumption, you might think it will print 0, then stop. But 
it doesn't. It prints 0, then 1, then 2, then 3, then 4. Each time 
through the loop it jumps back to the beginning, gets the next value 
from the range, and only when there are no more values to get does the 
for-loop finish.


-- 
Steven



More information about the Tutor mailing list