Now, we will have a look at how we can use looping operations to simplify repetition, allowing us to perform tasks across items or count through fixed numbers efficiently.
Loops are repetition instructions¶
We can loop (or iterate) over elements in a collection. You can think about loops as a way of acting on each item one by one. In a for loop, we can read it as “for each item in a group”. For example, if we want to read each page in a book, the following for loop means “for each page in the book, read it.”:
pages = [1, 2, 3, 4, 5]
for page in pages:
print(f"Reading page {page}")Reading page 1
Reading page 2
Reading page 3
Reading page 4
Reading page 5
Here, we loop over each item/element of the list starting from the first. In each iteration of the loop, we assign the value to a variable called page which is then printed. Note that, unlike in some other programming languages, page still exists after the loop has finished and contains the last value it was assigned (here 5).
As a more practical application, imagine you’re in a classroom and need to hand out worksheets to each student. You wouldn’t want to say, “Hand this to the first student, then hand it to the second student, then hand it to the third student...”:
students = ["Alice", "Bob", "Charlie", "Daisy"]
print(f"Handing worksheet to {students[0]}")
print(f"Handing worksheet to {students[1]}")
print(f"Handing worksheet to {students[2]}")
print(f"Handing worksheet to {students[3]}")Handing worksheet to Alice
Handing worksheet to Bob
Handing worksheet to Charlie
Handing worksheet to Daisy
Instead, you’d say, “Hand this to every student one after the other.” This is the core of a loop: it lets you avoid doing the same task individually and instead repeats it for each item in a group.
students = ["Alice", "Bob", "Charlie", "Daisy"]
for student in students:
print(f"Handing worksheet to {student}")Handing worksheet to Alice
Handing worksheet to Bob
Handing worksheet to Charlie
Handing worksheet to Daisy
Now think about having 30 students, or even 100. Without a loop, you would then have to write the print statement 30 or 100 times, while the loop would stay completely identical and only take 2 lines of code. This is why using loops is such a useful thing to do!
Counting loops: Doing something a fixed number of times¶
One very common use case of loops is to perform a specific action a set number of times. In Python, we can use the built-in range() function to count for us, so we don’t have to write each number ourselves. It’s like setting a timer for an exercise, where you know you’ll do an activity for 10 seconds or repeat it 5 times.
for i in range(5):
print(f"Jumping jack #{i}")Jumping jack #0
Jumping jack #1
Jumping jack #2
Jumping jack #3
Jumping jack #4
Here, range(5) tells the loop to repeat 5 times, counting from 0 to 4. The variable i is called an index variable. You can also give range() both a start and an end value:
for i in range(5,10):
print(f"Jumping jack #{i}")Jumping jack #5
Jumping jack #6
Jumping jack #7
Jumping jack #8
Jumping jack #9
Note that, just like with slicing, the end point of the range() function is exclusive, meaning range(5,10) creates a sequence of numbers from 5 to 9. As in the first example, you can also provide only a single number (like the length of a list) and use the numbers created by range as indices to index another variable:
my_list = ["apple", "banana", 3, 4]
list_length = len(my_list)
for i in range(list_length):
print(my_list[i])apple
banana
3
4
Using enumerate()¶
You have previously seen two ways of looping over a list. Either by indexing the items directly, or through indexing by using the range(len()) expression. Python also provides a nice way of combining these two through the enumerate() function:
for index, value in enumerate(my_list):
print(f"Index {index} contains: {value}")Index 0 contains: apple
Index 1 contains: banana
Index 2 contains: 3
Index 3 contains: 4
In cases where you need to keep track of the index, this approach is often preferred because it avoids manual indexing, making the code cleaner and less prone to errors.
While loops: “Keep going until...”¶
While loops are like a task that repeats until a certain condition is met. For example, think of heating water in a kettle. You’ll keep heating the water until it reaches boiling point. In code, this looks like a while loop, which keeps running until a specified condition is no longer true.
temperature = 20 # starting temperature
while temperature < 100:
print(f"Heating... temperature is {temperature}°C")
temperature += 10 # increase temperature
print("Water is boiling!")Heating... temperature is 20°C
Heating... temperature is 30°C
Heating... temperature is 40°C
Heating... temperature is 50°C
Heating... temperature is 60°C
Heating... temperature is 70°C
Heating... temperature is 80°C
Heating... temperature is 90°C
Water is boiling!
In this example, the loop keeps increasing the temperature until it reaches 100°C. Then, it stops.
Be careful with while loops because if the condition never becomes False, the loop will run indefinitely, leading to an infinite loop.
Using counters¶
Sometimes it can be useful to keep track of things happening in a loop. A concept you will see often is the use of counters:
counter = 0
while counter < 5:
print(f"Counter is {counter}")
counter += 1Counter is 0
Counter is 1
Counter is 2
Counter is 3
Counter is 4
Here, counter is a counting variable which is initialized and set to 0 before the loop. It then keeps track of something within a loop and, importantly, lets you access this result later on in your script.
Nested statements¶
In more complex analyses, you often need to nest multiple statements inside one another. If you for example want to iterate over an entire list and perform an action only for specific items of the list you could do this as follows:
my_list = ["apple", "banana", 3, 4]
for item in my_list:
if item == "banana":
print("Banana!")
else:
print("Not a banana.")Not a banana.
Banana!
Not a banana.
Not a banana.
Whitespace is syntactically required¶
One important thing which we have not yet covered explicitly is how the code within if-statements or for-loops is indented (shifted to the right). You might think this is just a way of making the code easier to read, and that would be true for almost all other programming languages. However, Python is a bit different in that regard by requiring you to use whitespace with certain rules.
Simply put, whenever you use a compound statement (which includes for-loops, conditionals, and also classes and functions which we will cover later), you need to increase the indentation of your code. Once you exit the compound statement, you decrease the indentation level by the same amount. The amount of this indentation is technically up to you, however the Python style guide recommends you to use four spaces. As an example, if we want to continue with the script after the for-loop, we would reset the indentation to the same level as the first for:
for item in my_list:
if item == "banana":
print("Banana!")
print("Continue after the for-loop...")Banana!
Continue after the for-loop...