# List of numbers
numbers = [10, 20, 30, 40, 50]
# Iteration variable
for num in numbers:
print("Number:", num)
Number: 10
Number: 20
Number: 30
Number: 40
Number: 50
Loops are control structures that allow us to execute a block of code repeatedly. Each executions is called an iteration. For example, when you count from 1 to 10, you are iterating over the numbers from 1 to 10.
Code within loops can be executed either a specific number of times (definite loop) or until a certain condition is met (indefinite loop).
In Python, there are two main loop structures:
for
loops (definite loops)while
loops (indefinite loops)Most of these structures can be used interchangeably, but each has its own use case.
Loops consist of three main elements:
i = 1
, count = 0
, etc.i <= 10
, count < 5
, etc.i += 1
, count += 1
, etc.Loops add complexity to the program control flow. To better understand the execution sequence:
In the following, we will cover different applications of loops in Python. Consider coming back to these examples after learning the details of each loop structure.
Loops allow you to process each element in a list or collection. For example:
Each iteration can update a variable to calculate the aggregate. For example:
def summary_statistics(numbers):
if len(numbers) == 0:
return 0, 0, 0
# Variables to store summary statistics
total = 0
count = 0
for num in numbers:
total += num
count += 1
average = total / count
return count, total, average
def test_summary_statistics():
assert summary_statistics([1, 2, 3, 4, 5]) == (5, 15, 3)
assert summary_statistics([10, 20, 30, 40, 50]) == (5, 150, 30)
assert summary_statistics([1, 1, 1, 1, 1]) == (5, 5, 1)
assert summary_statistics([]) == (0, 0, 0)
test_summary_statistics()
Loops can repeatedly prompt for user input until a valid value is entered. For example:
Loops can be used to search for specific elements in a collection. For example:
def search_max_number(list):
if len(list) == 0:
return None
max_number = list[0]
for num in list:
if num > max_number:
max_number = num
return max_number
def test_search_max_number():
assert search_max_number([1, 2, 3, 4, 5]) == 5
assert search_max_number([5, 4, 3, 2, 1]) == 5
assert search_max_number([1, 3, 5, 2, 4]) == 5
assert search_max_number([1, 1, 1, 1, 1]) == 1
assert search_max_number([1]) == 1
assert search_max_number([]) == None
test_search_max_number()
With loops, the same code block can be executed multiple times to generate patterns or sequences. If the sequence obeys a logic that depends on the iteration number, loops are a good choice. For example:
range(2, 0)
and range(2, 1)
will not generate any prime numbers (range
will return {python} list(range(2,0))
).
def prime_numbers_until(n):
"""Generate prime numbers up to n.
A prime number is a number greater than 1 that has no
positive divisors other than 1 and itself.
Parameters:
----------
n : int
The upper limit of the prime numbers.
Returns:
-------
list
A list of prime numbers up to n.
"""
prime_numbers = []
for num in range(2, n):
is_prime = True
for i in range(2, num):
if num % i == 0:
is_prime = False
break
if is_prime:
prime_numbers.append(num)
return prime_numbers
def test_prime_numbers_until():
assert prime_numbers_until(0) == []
assert prime_numbers_until(1) == []
assert prime_numbers_until(2) == []
assert prime_numbers_until(10) == [2, 3, 5, 7]
assert prime_numbers_until(20) == [2, 3, 5, 7, 11, 13, 17, 19]
print(list(range(2,0)))
test_prime_numbers_until()
[]
Loops can be used to repeat actions or apply the same operation to multiple elements. For example:
def send_email(email, subject, body):
# Code to send an email
print("Sending email to:", email)
print("Subject:", subject)
print("Body:", body)
def send_emails_example():
# List of tuples containing names and emails
contacts = [
("Alice", "alice@example.com"),
("Bob", "bob@example.com"),
("Charlie", "charlie@example.com"),
]
for name, email in contacts:
send_email(email, "Subject", f"Hello {name}, this is a test email.")
send_emails_example()
Sending email to: alice@example.com
Subject: Subject
Body: Hello Alice, this is a test email.
Sending email to: bob@example.com
Subject: Subject
Body: Hello Bob, this is a test email.
Sending email to: charlie@example.com
Subject: Subject
Body: Hello Charlie, this is a test email.
In the following sections, we will cover the different loop structures in Python. These structures allow you to repeat a block of code a specified number of times or until a certain condition is met.
The loop structures in Python are similar to those in other programming languages. If you learn loops in Python, you will be able to apply the same concepts in other languages like Java or C++.
for
Loop (Definite)When you know in advance how many times you want to execute a block of code, you can use a for
loop. In this structure, the loop configuration, namely the initialization, stop condition, and increment, are defined in a single line, at the beginning of the loop. In Figure 15.1, we have the structure of a For
loop. Notice that the condition is checked at the beginning of the loop. Then, the loop body is executed if the condition is True
and the iteration variable is updated before checking the condition again.
graph LR Start((Start))-->for for --> LoopStart[Initialize<br>iteration variable<br>Define Stop Condition and <br>Configure Increment] LoopStart-->Condition{Condition} Condition-->|True|Statement1["`**Loop Body** Statement 1 Statement 2 ... Statement N`"] Statement1 --> ForNext["Update iteration variable"] ForNext --> Condition Condition{Condition} ---->|False| End((End))
for
loop. The loop is configured at the beginning, with the initialization, stop condition, and increment. The condition is checked at the beginning of the loop. Then, the loop body is executed if the condition is True
. If the condition is False
, the loop is exited. After executing the loop body, the iteration variable is updated before checking the condition again.
In the Listing 15.3, the for
loop prints the numbers from 1 to 5. The range()
function generates a sequence of numbers from the start value (inclusive) to the end value (exclusive). The parameters of the range()
function are start
, stop
, and step
:
start
: The starting value of the sequence (default is 0).stop
: The end value of the sequence (exclusive).step
: The increment or decrement value (default is 1).In Table 15.1, we show examples of using the range()
function.
range()
function.
Function Call | Description | Output |
---|---|---|
range(5) |
Generates numbers from 0 to 4 | 0, 1, 2, 3, 4 |
range(1, 6) |
Generates numbers from 1 to 5 | 1, 2, 3, 4, 5 |
range(1, 11, 2) |
Generates numbers from 1 to 10, incrementing by 2 | 1, 3, 5, 7, 9 |
range(5, 0, -1) |
Generates numbers from 5 to 1, decrementing by 1 | 5, 4, 3, 2, 1 |
for
loop that prints the numbers from 1 to 5. The loop will run as long as i
is less than 6.
The elements are as follows:
i = 1
. The loop variable i
is initialized to 1.i < 6
. The loop will run as long as i
is less than 6.i += 1
. The loop variable i
is incremented by 1 after each iteration.for
LoopIn Python, the range()
function can accept a step
argument, allowing you to specify the increment or decrement value. For example, range(1, 11, 2)
will generate numbers from 1 to 10, incrementing by 2.
Iteration 1
Iteration 3
Iteration 5
Iteration 7
Iteration 9
If you want to decrement the loop variable, you can use a negative value for step
.
Nested loops are loops within loops. They are useful when you need to perform multiple iterations based on different conditions.
When using nested loops, the inner loop will complete all its iterations before the outer loop moves to the next iteration.
For example:
for i in range(1, 4): # Outer loop runs from 1 to 3
for j in range(1, 3): # Inner loop runs from 1 to 2
print(f"Outer Loop: {i}, Inner Loop: {j}")
Outer Loop: 1, Inner Loop: 1
Outer Loop: 1, Inner Loop: 2
Outer Loop: 2, Inner Loop: 1
Outer Loop: 2, Inner Loop: 2
Outer Loop: 3, Inner Loop: 1
Outer Loop: 3, Inner Loop: 2
for ... in
LoopThe for ... in
loop is used to iterate through elements of a collection or iterable object. With the for
loop, you can process each item in a collection without knowing its size in advance.
for ... in
loop that iterates over a list of fruits. The loop will run for each element in the list and print the name of the fruit.
while
Loop (Indefinite)This loop allows us to repeat a block of code until a certain condition is met. It can be used when the number of iterations is not known in advance.
In Figure 15.2, we have the structure of a while
loop. Notice that the condition is checked at the beginning of the loop. Then, the loop body is executed if the condition is True
.
graph LR Start((Start)) --> LoopStart[Initialize<br>iteration variable] LoopStart --> While[while] While-->Condition{Condition} Condition--True-->Statement1["`**Loop Body** Statement 1 Statement 2 ... Statement N _(Update iteration variable)_`"] Statement1--->Condition Condition ---->|False| End((End))
while
loop. Notice that the condition is checked at the beginning of the loop. Then, the loop body is executed if the condition is True
. If the condition is False
, the loop is exited. Inside the loop, the iteration variable is updated before checking the condition again.
In the code example below, we have a while
loop that prints the numbers from 1 to 5.
while
loop that prints the numbers from 1 to 5. The loop will run as long as count
is less than or equal to 5. First, the iteration variable count
is initialized to 1. Then, the loop body is executed while count
is less than or equal to 5. The loop body prints the value of count
and increments count
by 1. The loop stops when count
is greater than 5.
# Iteration variable
count = 1
# Stop condition (stop if evaluates to False; loop as long as
# count is lower or equal than 5)
while count <= 5:
print("Count:", count)
# Increment iteration variable
count += 1
# End of loop: Send the flow back to the condition
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
Sometimes you want to ensure that the loop runs at least once. In this case, you can use a while True
loop with a break
statement. In Listing 15.5, we have a standard while
loop that prints the numbers from 1 to 5. In Listing 15.6, we have a while True
loop that prints the number 6. Notice that count
starts with 6 (i.e., the stop condition is True
) but the code block within the loop is executed nevertheless. This happens because the condition is checked at the end of the loop.
graph LR Start((Start)) --> LoopStart[Initialize<br>iteration variable] LoopStart --> While[while True] While-->Statement1["`**Loop Body** Statement 1 Statement 2 ... Statement N _(Update iteration variable)_`"] Statement1--->Condition -->|True| While Condition{While<br>Condition} -->|False| End((End))
Do
… Loop While
loop, the loop body is executed before checking the stop condition. This allows the loop to run at least once, even if the stop condition is already met.
while True
loop that prints the number 6. The iteration variable count
is initialized to 6. The loop body prints the value of count
and increments count
by 1. The loop stops when count
is equal to 5. Notice that the loop body is executed at least once, even if the stop condition is already met.
Checking the condition at the end is especially useful when you need to validate user input before entering the loop. For example, in the code below, the user is prompted to enter a number between 1 and 100. The loop will keep asking for input until a valid number is entered.
def validate_input():
while True:
user_input = int(input("Enter a number between 1 and 100: "))
if 1 <= user_input <= 100:
break
return user_input
If we did not use a while True
loop, we would need to duplicate the input prompt code before the loop to ensure that the loop runs at least once:
continue
StatementSometimes you need to skip part of the code in a loop and continue to the next iteration. The continue
statement:
Using continue
, you can skip code for certain iterations.
for i in range(1, 6):
# Skipping iterations 2 and 4
if i == 2 or i == 4:
print("Skipping", i)
continue
# This part of the code is skipped if continue is called
print("Iteration", i)
Iteration 1
Skipping 2
Iteration 3
Skipping 4
Iteration 5
Whe can also use continue
in a while
loop. In the example below, we skip the number 3.
break
StatementSometimes you need to exit a loop before it completes all iterations. To prematurely exit loops when a condition is met, you can use the break
statement.
In Listing 15.7, we have a for
loop that will break when i
is equal to 5. In Listing 15.8, we have a while True
loop that will break when count
is greater than 5.
for
loop that ends prematurely. The loop is supposed to run from 1 to 10, but it stops when i
is equal to 5. The loop prints the numbers from 1 to 4 and then prints “Finished execution.”
while True
loop that ends prematurely. The loop is supposed to run indefinitely, but it stops when count
is greater than 5. The loop prints the numbers from 1 to 5 and then prints “Finished program.”
Write a function named cumulative_sum_numbers
that takes an integer n
as input and returns the sum of all numbers from 1 to n
.
Write a function named factorial
that takes an integer n
as input and returns the factorial of n
.
Write a function named power
that takes two numbers, x
and y
, as input and returns x
raised to the power of y
. Use a loop to calculate the power.
Write a function named is_prime
that takes an integer n
as input and returns True
if n
is a prime number, otherwise returns False
.
Write a function named avg_numbers
that takes an integer n
as input and returns the average of all numbers from 1 to n
.
Write a function named sum_odd_numbers
that takes an integer n
as input and returns the sum of all odd numbers from 1 to n
.
Write a function named print_triangle_pattern
that prints a triangle pattern of asterisks (*
) to the console.
The function takes as input:
n
: an integer representing the height of the triangleside
: a string, either "left"
or "right"
indicating the alignment of the triangleAnd prints the triangle pattern of n
lines aligned to the left or right.
def print_triangle_pattern(n, side):
pass # Add code here!
def test_print_triangle_pattern():
print("Left Aligned Triangle:")
print_triangle_pattern(4, "left")
# Expected output:
# *
# **
# ***
# ****
print("\nRight Aligned Triangle:")
print_triangle_pattern(4, "right")
# Expected output:
# *
# **
# ***
# ****
Write a function named print_x_pattern
that takes an integer n
as input and prints an “X” pattern of asterisks (*
) to the console.
Write a function named reverse_string
that takes a string s
as input and returns a new string with the characters of s
reversed.
len()
to get the size of the string.Write a function named count_vowels
that takes a string s
as input and returns the count of vowels (A, E, I, O, U) in the string.
Write a function named remove_spaces
that takes a string s
as input and returns a new string with all spaces removed. (Do not use string methods like replace
or split
.)
Write a function named two_different_numbers
that takes two integer parameters, min_range
and max_range
. It returns two different random numbers within the specified range. Ensure the two generated numbers are different.
Use the random.randint(a, b)
function to generate the numbers. For example, random.randint(1, 10)
will generate a random number between 1 and 10, inclusive.
import random
def two_different_numbers(min_range, max_range):
# This code will generate random sequences
random.seed(400) # Change this number to get new sequences
pass # Add code here!
def test_two_different_numbers():
min_max = [(1, 10), (50, 100), (200, 300)]
for min_range, max_range in min_max:
a, b = two_different_numbers(min_range, max_range)
assert a != b
test_two_different_numbers()
Write a function named find_random_number
that repeatedly generates random numbers until it finds a number less than 50.
Write a function named generate_random_prime
that repeatedly generates random numbers until it finds a prime number. Stop when a prime number is found, and print how many iterations it took to find the prime number.
Create a function is_prime
to be used inside the loop.
import random
def is_prime(n):
pass # Add code here!
def generate_random_prime():
# This code will generate random sequences
random.seed(400) # Change this number to get new sequences
pass # Add code here!
def test_generate_random_prime():
generate_random_prime()
# Expected output with random seed 45:
# Random Prime Number: 67 / #Iterations: 1
# Expected output with random seed 7:
# Random Prime Number: 7 / #Iterations: 2
# Expected output with random seed 400:
# Random Prime Number: 53 / #Iterations: 6
Write a function named largest_digit
that takes an integer n
as input and returns the largest digit in n
.