13  Python for Loops

TipLearning Objectives
  • Learn what a for loop is and its syntax
  • Learn how to iterate over sequences, including lists and dictionaries
  • Understand how helper functions like range() and enumerate() work

13.1 Syntax of for Loops in Python

for loops iterate over a sequence (such as a list, tuple, string, dictionary, set, or range) and execute a block of code for each item in that sequence.

Syntax

  • The for keyword is followed by a variable name (e.g., item) that receives the current element on each iteration.
  • The in keyword points to the sequence or iterable object.
  • The colon (:) marks the start of the loop body.
  • The code block inside the loop must be indented (typically 4 spaces).
for item in sequence:
    print(item)  # Code block executed for each item

Example:

animals = ["dog", "cat", "rabbit", "elephant", "tiger"]

for animal in animals:
    print(f"I have a {animal}.")
I have a dog.
I have a cat.
I have a rabbit.
I have a elephant.
I have a tiger.

13.2 Iterating Through a Dictionary

When you iterate directly over a dictionary, Python defaults to looping through its keys. However, you can also iterate over its values or both keys and values together using dictionary methods.

student_scores = {
    "Alice": 85,
    "Bob": 92,
    "Charlie": 78
}

# 1. Loop through keys (default behaviour)
print("Keys:")
for name in student_scores:
    print(name)

# 2. Loop through values using .values()
print("\nValues:")
for score in student_scores.values():
    print(score)

# 3. Loop through key-value pairs using .items()
print("\nKey-Value Pairs:")
for name, score in student_scores.items():
    print(f"{name} scored {score}%")
Keys:
Alice
Bob
Charlie

Values:
85
92
78

Key-Value Pairs:
Alice scored 85%
Bob scored 92%
Charlie scored 78%

13.3 Understanding and Using range()

The range() function generates a sequence of numbers. Beginners often expect range(5) to produce a list of numbers directly, but let’s test what happens if you print it:

print(range(5))
range(0, 5)

What is a range object?

Instead of generating all numbers in memory at once, range() creates a range object. This object generates each number on-the-fly as requested (a concept known as lazy evaluation).

To inspect the numbers contained inside a range object, you can convert it to a list:

print(list(range(5)))
[0, 1, 2, 3, 4]

How for loops use range()

When used in a for loop, the loop requests numbers from the range object one by one:

for num in range(5):
    print(num)
0
1
2
3
4

Syntax Options for range()

The syntax for range() is range(start=0, stop, step=1):

  • range(stop): Starts at 0 by default and goes up to, but does not include, stop.
  • range(start, stop): Starts at start and goes up to, but does not include, stop.
  • range(start, stop, step): Increments by step on each iteration, with the default step being 1.
# Range with start and stop
for i in range(2, 6):
    print(i, end=" ")  # Output: 2 3 4 5
    # the end= replaces the default new line with a space
print()

# Range with start, stop, and step
for i in range(0, 10, 2):
    print(i, end=" ")  # Output: 0 2 4 6 8
print()
2 3 4 5 
0 2 4 6 8 

Combining range() and len()

You can combine range() and len() to loop using index positions:

animals = ["dog", "cat", "rabbit", "elephant"]

for i in range(len(animals)):
    print(f"Index {i}: {animals[i]}")
Index 0: dog
Index 1: cat
Index 2: rabbit
Index 3: elephant

13.4 Understanding and Using enumerate()

While range(len(...)) works for index-based access, Python provides a cleaner tool called enumerate().

If you try printing an enumerate call directly:

animals = ["dog", "cat", "rabbit"]
print(enumerate(animals))
<enumerate object at 0x1038990d0>

Just like range(), enumerate() produces an object that yields values on demand. Converting it to a list shows what it generates under the hood:

print(list(enumerate(animals)))
[(0, 'dog'), (1, 'cat'), (2, 'rabbit')]

Each element is a tuple containing (index, item).

Using enumerate() in a for loop

In a for loop, Python unpacks these two-element tuples directly into two variables:

animals = ["dog", "cat", "rabbit", "elephant"]

for index, animal in enumerate(animals):
    print(f"Animal {index}: {animal}")
Animal 0: dog
Animal 1: cat
Animal 2: rabbit
Animal 3: elephant

You can also specify a custom starting index using start:

for index, animal in enumerate(animals, start=1):
    print(f"#{index} - {animal}")
#1 - dog
#2 - cat
#3 - rabbit
#4 - elephant

Benefits of enumerate():

  • Cleaner, more readable code than range(len(...)).
  • Automatically tracks indices without manual counter variables.

13.5 Practice Exercises

ExerciseExercise 1 - Summing Numbers with range()

Level:

Write a for loop that calculates the sum of all numbers from 1 to 10 (inclusive) using range(). Print the final sum.

total = 0
for num in range(1, 11):
    total += num

print(f"The sum is: {total}")  # Output: The sum is: 55
The sum is: 55
ExerciseExercise 2 - Shopping Cart Total

Level:

Given a dictionary of shop items and their prices in pounds, write a for loop using .items() to print each item’s price and calculate the total cost of all items.

cart = {
    "apple": 0.80,
    "bread": 2.50,
    "milk": 1.20,
    "cheese": 3.40
}
cart = {
    "apple": 0.80,
    "bread": 2.50,
    "milk": 1.20,
    "cheese": 3.40
}

total_cost = 0.0

for item, price in cart.items():
    print(f"{item.capitalize()}: £{price:.2f}")
    total_cost += price

print(f"Total: £{total_cost:.2f}")
Apple: £0.80
Bread: £2.50
Milk: £1.20
Cheese: £3.40
Total: £7.90
ExerciseExercise 3 - Numbered Shopping List

Level:

Given the following list of tasks, use enumerate() with start=1 to print a formatted to-do list:

tasks = ["Write report", "Send emails", "Review code", "Attend meeting"]

Expected Output:

Task 1: Write report
Task 2: Send emails
Task 3: Review code
Task 4: Attend meeting
tasks = ["Write report", "Send emails", "Review code", "Attend meeting"]

for number, task in enumerate(tasks, start=1):
    print(f"Task {number}: {task}")
Task 1: Write report
Task 2: Send emails
Task 3: Review code
Task 4: Attend meeting

13.6 Extra: List Comprehensions

List comprehensions provide a concise way to create lists using for loops in a single line.

Syntax:

[expression for item in iterable if condition]
ExerciseExercise 4 - Use List Comprehensions

Level:

Convert the list of animals to uppercase using a list comprehension:

animals = ["dog", "cat", "rabbit", "elephant"]
animals = ["dog", "cat", "rabbit", "elephant"]
uppercase_animals = [animal.upper() for animal in animals]
print(uppercase_animals)
['DOG', 'CAT', 'RABBIT', 'ELEPHANT']
ExerciseExercise 5 - for loops in the expense calculator

Level:

In the expense calculator, the function in the summary.py script iterates through the expenses to generate a summary. Modify display_summary() to use enumerate() to print a numbered summary and test your script in the Jupyter notebook.

animals = ["dog", "cat", "rabbit", "elephant"]
def display_summary(expenses):
    """Uses enumerate to iterate through the data and print a numbered report."""
    print("\n--- Expense Summary ---")
    for index, item in enumerate(expenses, start=1):
        category = item[0]
        amount = item[1]
        print(f"{index}. Category: {category.capitalize()} | Amount: £{amount:.2f}")
    print("-----------------------\n")

# Testing the updated function
sample_expenses = [["food", 20.50], ["transport", 10.00], ["entertainment", 90.00]]
display_summary(sample_expenses)

--- Expense Summary ---
1. Category: Food | Amount: £20.50
2. Category: Transport | Amount: £10.00
3. Category: Entertainment | Amount: £90.00
-----------------------

13.7 Summary

TipKey Points
  • for loops iterate through elements of sequences (lists, strings, ranges, dictionaries).
  • Dictionaries iterate over keys by default; use .values() for values and .items() for key-value pairs.
  • range() returns an iterable range object (not a pre-built list), generating numbers on demand.
  • enumerate() yields (index, item) pairs, making indexed loops cleaner and safer.