Introduction
In this lesson, you will learn how to use for loops to iterate over sequences in Python efficiently and clearly. Building on your knowledge of variables, strings, and basic control flow, we will:
- Traverse lists, tuples, strings, and ranges
- Use both item-based and index-based iteration
- Leverage
range()for counting and custom step sizes - Nest
forloops to process multi-dimensional data - Use
enumerate()andzip()to write clean, expressive iteration patterns
By the end, you’ll be able to choose the right iteration style for a given problem and write more concise, readable loop code.
Basics of for Loops Over Sequences
A for loop lets you go through each element of a sequence (like a list, tuple, or string) and do something with it.
Iterating Over Lists and Tuples (Item-Based)
Item-based iteration means you work directly with each element, not its index.
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(f"I like {fruit}")
# Output
I like apple
I like banana
I like cherry
Explanation:
fruittakes each value fromfruitsin order.- This is the most Pythonic way to loop when you don’t need the index.
You can do the same with tuples:
coordinates = (10, 20, 30)
for value in coordinates:
print(value * 2)
# Output
20
40
60
Iterating Over Strings
Strings are sequences of characters, so you can loop through them directly.
message = "loop"
for ch in message:
print(ch)
# Output
l
o
o
p
This is useful for tasks like counting specific characters or validating input.
Index-Based vs Item-Based Iteration
Sometimes you need the position (index) of each element, not just the value.
Manual Index-Based Iteration Using range()
numbers = [10, 20, 30, 40]
for i in range(len(numbers)):
print(f"Index: {i}, Value: {numbers[i]}")
# Output
Index: 0, Value: 10
Index: 1, Value: 20
Index: 2, Value: 30
Index: 3, Value: 40
Explanation:
range(len(numbers))generates indices0to3.- This pattern works, but
enumerate()(covered later) is usually cleaner.
When to Prefer Item-Based Iteration
Use item-based loops when:
- The index doesn’t matter.
- You only care about the element itself.
Use index-based loops when:
- You must update elements in-place in a list.
- You need both the index and the value and don’t want
enumerate()(legacy code, etc.).
Using range() for Counting Loops
range() is a powerful tool for numeric iteration.
Basic Counting
for i in range(5): # 0 to 4
print(i)
# Output
0
1
2
3
4
Custom Start and End
for i in range(3, 7): # 3 to 6
print(i)
# Output
3
4
5
6
Using a Step (Increment or Decrement)
for i in range(0, 20, 5): # start=0, stop=20, step=5
print(i)
# Output
0
5
10
15
You can also count down using a negative step:
for i in range(10, 0, -2):
print(i)
# Output
10
8
6
4
2
range() is ideal when you know exactly how many times you want to loop.
Nested for Loops and Multi-Dimensional Data
Nested loops are loops inside other loops. They’re especially useful for matrices or lists of lists.
Example: Iterating Over a Matrix (List of Lists)
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
for row in matrix: # Outer loop over rows
for value in row: # Inner loop over values in each row
print(value, end=" ")
print() # new line after each row
# Output
1 2 3
4 5 6
7 8 9
Explanation:
- The outer loop picks each
row(which is itself a list). - The inner loop goes through each number in that
row. - This pattern scales to more complex structures like game boards or grids.
Example: Building a Multiplication Table
for i in range(1, 4):
for j in range(1, 4):
print(f"{i*j:2}", end=" ")
print()
# Output
1 2 3
2 4 6
3 6 9
This shows how nested loops combine indices or counters for multi-dimensional calculations.
Using enumerate() for Index + Value
enumerate() is a built-in that gives you both the index and the value in a clean way.
names = ["Alice", "Bob", "Charlie"]
for index, name in enumerate(names):
print(f"Guest #{index + 1}: {name}")
# Output
Guest #1: Alice
Guest #2: Bob
Guest #3: Charlie
Explanation:
enumerate(names)produces pairs like(0, "Alice"),(1, "Bob").- You unpack those into
indexandnamedirectly.
You can also change the starting index:
for seat_number, name in enumerate(names, start=101):
print(f"Seat {seat_number}: {name}")
# Output
Seat 101: Alice
Seat 102: Bob
Seat 103: Charlie
Using zip() to Iterate Over Multiple Sequences
zip() lets you loop over multiple sequences in parallel.
Example: Combining Two Lists
students = ["Anna", "Ben", "Cara"]
scores = [88, 92, 79]
for student, score in zip(students, scores):
print(f"{student} scored {score}")
# Output
Anna scored 88
Ben scored 92
Cara scored 79
Explanation:
zip(students, scores)pairs elements by position:("Anna", 88), etc.- The loop unpacks each pair into
studentandscore.
Example: Zipping Three Sequences
products = ["Book", "Pen", "Notebook"]
prices = [12.5, 1.2, 4.0]
quantities = [2, 10, 3]
for product, price, qty in zip(products, prices, quantities):
total = price * qty
print(f"{product}: {qty} x {price} = {total}")
# Output
Book: 2 x 12.5 = 25.0
Pen: 10 x 1.2 = 12.0
Notebook: 3 x 4.0 = 12.0
zip() will stop when the shortest sequence is exhausted, which helps avoid index errors.
Summary / Key Takeaways
In this lesson on for loops and iterating over sequences, you have learned:
- Item-based iteration is the default, Pythonic way to traverse lists, tuples, and strings when you don’t need indices.
- Index-based iteration using
range(len(sequence))is useful when you must access or modify elements by position. range()supports flexible counting loops with configurable start, stop, and step values, including reverse counting.- Nested
forloops allow you to process multi-dimensional data structures such as matrices or lists of lists. enumerate()provides a clean way to access both index and value during iteration, with optional custom starting indices.zip()lets you iterate over multiple sequences in parallel by pairing elements at the same positions.- Choosing the right pattern (plain
for,range(),enumerate(), orzip()) improves code readability and reduces off-by-one and indexing errors. - Loop structure and data shape go hand-in-hand: your choice of nesting and helpers like
enumerate()andzip()should reflect how your data is organized.
