Loop Structures in Python

by Pyrastra Team
Loop Structures in Python

When writing programs, we’re very likely to encounter scenarios where we need to repeatedly execute certain instructions. For example, we need to output “hello, world” on the screen every second and continue for one hour. The code shown below can complete this operation once. If we want to continue outputting for one hour, we would need to write this code 3600 times. Would you be willing to do that?

import time

print('hello, world')
time.sleep(1)

Note: Python’s built-in time module’s sleep function can implement program sleep. The parameter 1 represents the number of seconds to sleep, which can use int or float types. For example, 0.05 represents 50 milliseconds. We’ll explain functions and modules in subsequent lessons.

To address the problem in the above scenario, we can use loop structures in Python programs. A loop structure is a structure in a program that controls the repeated execution of certain instructions. With such a structure, the code just mentioned doesn’t need to be written 3600 times, but rather written once and then placed in a loop structure to repeat 3600 times. In Python, there are two ways to construct loop structures: one is the for-in loop, and the other is the while loop.

for-in Loop

If we clearly know the number of times the loop will execute, we recommend using the for-in loop. For example, in the scenario mentioned above that repeats 3600 times, we can use the following code to implement it. Note that the code block controlled by the for-in loop is also constructed through indentation, which is the same as constructing code blocks in branch structures. We call the code block controlled by the for-in loop the loop body, and usually the statements in the loop body will be repeatedly executed according to the loop settings.

"""
Output "hello, world" every second for 1 hour

Author: Luo Hao
Version: 1.0
"""
import time

for i in range(3600):
    print('hello, world')
    time.sleep(1)

It should be noted that range(3600) in the code above can construct a range from 0 to 3599. When we put such a range into a for-in loop, we can sequentially extract integers from 0 to 3599 through the loop variable i in front, which will cause the statements in the for-in code block to repeat 3600 times. Of course, the usage of range is very flexible. The following list gives examples of using the range function:

  • range(101): Can be used to generate integers in the range 0 to 100. Note that 101 is not included.
  • range(1, 101): Can be used to generate integers in the range 1 to 100, equivalent to a left-closed right-open setting, i.e., [1, 101).
  • range(1, 101, 2): Can be used to generate odd numbers from 1 to 100, where 2 is the step (stride), i.e., the value incremented each time, and 101 is not included.
  • range(100, 0, -2): Can be used to generate even numbers from 100 to 1, where -2 is the step (stride), i.e., the value decremented each time, and 0 is not included.

You may have already noticed that the output operation and sleep operation in the code above don’t use the loop variable i. For for-in loop structures that don’t need to use the loop variable, according to Python programming conventions, we usually name the loop variable _. The modified code is shown below. Although the result doesn’t change much, writing it this way makes you look more professional and instantly raises your level.

"""
Output "hello, world" every second for 1 hour

Author: Luo Hao
Version: 1.1
"""
import time

for _ in range(3600):
    print('hello, world')
    time.sleep(1)

The code above takes one hour to execute. If you want to terminate the program early, in PyCharm you can click the stop button on the run window, as shown in the figure below. If running code in a command prompt or terminal, you can use the key combination ctrl+c to terminate the program.

Below, we use a for-in loop to implement the sum of integers from 1 to 100, i.e., $\small{\sum_{n=1}^{100}{n}}$.

"""
Sum of integers from 1 to 100

Version: 1.0
Author: Luo Hao
"""
total = 0
for i in range(1, 101):
    total += i
print(total)

In the code above, the variable total is used to save the accumulated result. During the loop, the value of loop variable i will range from 1 to 100. For each value of variable i, we execute total += i, which is equivalent to total = total + i. This statement implements the accumulation operation. So when the loop ends and we output the value of variable total, its value is the result of accumulating from 1 to 100, which is 5050. Note that the print(total) statement has no indentation and is not controlled by the for-in loop, so it won’t be repeatedly executed.

Let’s write code to sum even numbers from 1 to 100, as shown below.

"""
Sum of even numbers from 1 to 100

Version: 1.0
Author: Luo Hao
"""
total = 0
for i in range(1, 101):
    if i % 2 == 0:
        total += i
print(total)

Note: In the for-in loop above, we used a branch structure to determine whether the loop variable i is an even number.

We can also modify the parameters of the range function, changing the starting value and stride to 2, to implement the sum of even numbers from 1 to 100 with simpler code.

"""
Sum of even numbers from 1 to 100

Version: 1.1
Author: Luo Hao
"""
total = 0
for i in range(2, 101, 2):
    total += i
print(total)

Of course, an even simpler method is to use Python’s built-in sum function for summation, which saves us even the loop structure.

"""
Sum of even numbers from 1 to 100

Version: 1.2
Author: Luo Hao
"""
print(sum(range(2, 101, 2)))

while Loop

If we want to construct a loop structure but cannot determine the number of loop repetitions, we recommend using the while loop. The while loop controls the loop through boolean values or expressions that produce boolean values. When the boolean value or expression value is True, the statements in the loop body (the code block below the while statement that maintains the same indentation) will be repeatedly executed. When the expression value is False, the loop ends.

Below we use a while loop to implement the sum of integers from 1 to 100, as shown in the code below.

"""
Sum of integers from 1 to 100

Version: 1.1
Author: Luo Hao
"""
total = 0
i = 1
while i <= 100:
    total += i
    i += 1
print(total)

Compared to the for-in loop, in the code above we added a variable i before the loop starts. We use this variable to control the loop, so after while we give the condition i <= 100. In the loop body of while, besides accumulation, we also need to increment the value of variable i, so we added the statement i += 1. This way, the value of i will sequentially take 1, 2, 3, …, until 101. When i becomes 101, the condition of the while loop is no longer valid, and the code will leave the while loop. At this point, we output the value of variable total, which is the result of summing from 1 to 100, which is 5050.

If we want to implement the sum of even numbers from 1 to 100, we can slightly modify the code above.

"""
Sum of even numbers from 1 to 100

Version: 1.3
Author: Luo Hao
"""
total = 0
i = 2
while i <= 100:
    total += i
    i += 2
print(total)

break and continue

What happens if we set the condition of the while loop to True, making the condition always true? Let’s look at the code below, which still uses while to construct a loop structure to calculate the sum of even numbers from 1 to 100.

"""
Sum of even numbers from 1 to 100

Version: 1.4
Author: Luo Hao
"""
total = 0
i = 2
while True:
    total += i
    i += 2
    if i > 100:
        break
print(total)

The code above uses while True to construct a loop with a condition that is always true, which means that if no special handling is done, the loop won’t end. This is what we commonly call an “infinite loop”. To stop the loop when the value of i exceeds 100, we use the break keyword, which terminates the execution of the loop structure. It should be noted that break can only terminate the loop it’s in. This needs attention when using nested loop structures, which we’ll discuss later. Besides break, there’s another keyword that can be used in loop structures: continue. It can be used to abandon the subsequent code of the current loop iteration and directly let the loop enter the next round, as shown in the code below.

"""
Sum of even numbers from 1 to 100

Version: 1.5
Author: Luo Hao
"""
total = 0
for i in range(1, 101):
    if i % 2 != 0:
        continue
    total += i
print(total)

Note: The code above uses the continue keyword to skip cases where i is odd. Only when i is even will it execute to total += i.

Nested Loop Structures

Like branch structures, loop structures can also be nested, meaning loop structures can be constructed within loop structures. The example below demonstrates how to output a multiplication table (nine-nine table) through nested loops.

"""
Print multiplication table

Version: 1.0
Author: Luo Hao
"""
for i in range(1, 10):
    for j in range(1, i + 1):
        print(f'{i}×{j}={i * j}', end='\t')
    print()

In the code above, a for-in loop is used within the loop body of the for-in loop. The outer loop controls the generation of i rows of output, while the inner loop controls the output of j columns in one row. Obviously, the output of the inner for-in loop is a complete row in the multiplication table. So when the inner loop completes, we use print() to achieve a line break effect, making the following output start on a new line. The final output is shown below.

1×1=1
2×1=2	2×2=4
3×1=3	3×2=6	3×3=9
4×1=4	4×2=8	4×3=12	4×4=16
5×1=5	5×2=10	5×3=15	5×4=20	5×5=25
6×1=6	6×2=12	6×3=18	6×4=24	6×5=30	6×6=36
7×1=7	7×2=14	7×3=21	7×4=28	7×5=35	7×6=42	7×7=49
8×1=8	8×2=16	8×3=24	8×4=32	8×5=40	8×6=48	8×7=56	8×8=64
9×1=9	9×2=18	9×3=27	9×4=36	9×5=45	9×6=54	9×7=63	9×8=72	9×9=81

Applications of Loop Structures

Example 1: Determining Prime Numbers

Requirement: Input a positive integer greater than 1 and determine whether it’s a prime number.

Tip: Prime numbers are positive integers greater than 1 that can only be divided by 1 and themselves. For example, for a positive integer $\small{n}$, we can determine whether it’s a prime number by searching for factors of $\small{n}$ between 2 and $\small{n - 1}$. Of course, the loop doesn’t need to start from 2 and end at $\small{n - 1}$, because for positive integers greater than 1, factors should appear in pairs, so the loop can end at $\small{\sqrt{n}}$.

"""
Input a positive integer greater than 1 to determine if it's prime

Version: 1.0
Author: Luo Hao
"""
num = int(input('Please enter a positive integer: '))
end = int(num ** 0.5)
is_prime = True
for i in range(2, end + 1):
    if num % i == 0:
        is_prime = False
        break
if is_prime:
    print(f'{num} is prime')
else:
    print(f'{num} is not prime')

Note: In the code above, we used a boolean variable is_prime. We first assign it True, assuming num is a prime number. Next, we search for factors of num in the range from 2 to num ** 0.5. If we find a factor of num, then it’s definitely not a prime number. At this point, we assign is_prime to False and use the break keyword to terminate the loop structure. Finally, we give different outputs based on whether the value of is_prime is True or False.

Example 2: Greatest Common Divisor

Requirement: Input two positive integers greater than 0 and find their greatest common divisor.

Tip: The greatest common divisor of two numbers is the largest number among their common factors.

"""
Input two positive integers to find their greatest common divisor

Version: 1.0
Author: Luo Hao
"""
x = int(input('x = '))
y = int(input('y = '))
for i in range(x, 0, -1):
    if x % i == 0 and y % i == 0:
        print(f'Greatest common divisor: {i}')
        break

Note: In the code above, the loop variable value of the for-in loop goes from large to small. This way, the factor i we find that can simultaneously divide x and y is the greatest common divisor of x and y, at which point we use break to terminate the loop. If x and y are coprime, the loop will execute until i becomes 1, because 1 is a factor of all positive integers, and at this point the greatest common divisor of x and y is 1.

Finding the greatest common divisor with the code above has performance issues. Suppose the value of x is 999999999998 and the value of y is 999999999999. Obviously, the two numbers are coprime with a greatest common divisor of 1. But using the code above, the loop will repeat 999999999998 times, which is usually unacceptable. We can use the Euclidean algorithm to find the greatest common divisor, which can help us get the desired result faster, as shown in the code below.

"""
Input two positive integers to find their greatest common divisor

Version: 1.1
Author: Luo Hao
"""
x = int(input('x = '))
y = int(input('y = '))
while y % x != 0:
    x, y = y % x, x
print(f'Greatest common divisor: {x}')

Note: The methods and steps to solve a problem can be called an algorithm. For the same problem, we can design different algorithms. Different algorithms will differ in storage space occupation and execution efficiency, and these differences represent the quality of algorithms. You can compare the two pieces of code above to understand why we say the Euclidean algorithm is a better choice. The statement x, y = y % x, x in the code above means assigning the value of y % x to x and assigning the original value of x to y.

Example 3: Number Guessing Game

Requirement: The computer generates a random number between 1 and 100. The player inputs their guessed number, and the computer gives corresponding hints “bigger”, “smaller”, or “correct”. If the player guesses the number, the computer tells the user how many guesses it took and the game ends; otherwise, the game continues.

"""
Number guessing game

Version: 1.0
Author: Luo Hao
"""
import random

answer = random.randrange(1, 101)
counter = 0
while True:
    counter += 1
    num = int(input('Please enter: '))
    if num < answer:
        print('Bigger.')
    elif num > answer:
        print('Smaller.')
    else:
        print('Correct.')
        break
print(f'You guessed {counter} times.')

Note: The code above uses import random to import Python’s standard library random module. The randrange function of this module helps us generate a random number in the range 1 to 100 (not including 100). The variable counter is used to record the number of times the loop executes, i.e., how many times the user guessed. Each time the loop executes, the value of counter increases by 1.

Summary

Having learned about branch structures and loop structures in Python, we can now solve many practical problems. Through this lesson, everyone should already know that we can use the for and while keywords to construct loop structures. If we know the number of repetitions of the loop structure in advance, we usually use the for loop; if the number of repetitions of the loop structure cannot be determined, we can use the while loop. In addition, we can use break to terminate loops in loop structures, and we can also use the continue keyword in loop structures to let the loop structure directly enter the next round.