The for Loop and range()
Introduction
The for loop in Python iterates through elements of a sequence (list, string, range, etc.). It’s preferred when we know how many iterations we’ll make.
Basic Syntax
for element in sequence:
# code block
# executes for each element
Iterating through a list:
fruits = ["apple", "pear", "banana"]
for fruit in fruits:
print(fruit)
# apple
# pear
# banana
Iterating through a string:
for letter in "Python":
print(letter)
# P y t h o n (on separate lines)
The range() Function
range() generates a sequence of numbers for iteration.
range(stop) - from 0 to stop-1:
for i in range(5):
print(i)
# 0 1 2 3 4 (does NOT include 5!)
range(start, stop) - from start to stop-1:
for i in range(2, 6):
print(i)
# 2 3 4 5 (does NOT include 6!)
range(start, stop, step) - with step:
# Every 2
for i in range(0, 10, 2):
print(i)
# 0 2 4 6 8
# Countdown
for i in range(5, 0, -1):
print(i)
# 5 4 3 2 1
# Negative step
for i in range(10, 0, -2):
print(i)
# 10 8 6 4 2
Converting to list:
print(list(range(5))) # [0, 1, 2, 3, 4]
print(list(range(2, 7))) # [2, 3, 4, 5, 6]
print(list(range(0, 10, 3))) # [0, 3, 6, 9]
Iterating with Index
Using range and len:
fruits = ["apple", "pear", "banana"]
for i in range(len(fruits)):
print(f"{i}: {fruits[i]}")
# 0: apple
# 1: pear
# 2: banana
Using enumerate (recommended):
fruits = ["apple", "pear", "banana"]
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# 0: apple
# 1: pear
# 2: banana
# With different start
for i, fruit in enumerate(fruits, start=1):
print(f"{i}. {fruit}")
# 1. apple
# 2. pear
# 3. banana
Iterating Through Dictionaries
student = {"name": "Ana", "age": 20, "grade": 9}
# Keys only (implicit)
for key in student:
print(key)
# name age grade
# Keys explicitly
for key in student.keys():
print(key)
# Values
for value in student.values():
print(value)
# Ana 20 9
# Keys and values
for key, value in student.items():
print(f"{key}: {value}")
# name: Ana
# age: 20
# grade: 9
break and continue Statements
break - exits the loop:
for i in range(10):
if i == 5:
break
print(i)
# 0 1 2 3 4
continue - skips to next iteration:
for i in range(5):
if i == 2:
continue
print(i)
# 0 1 3 4 (without 2)
The else Clause with for
Executes if loop finished normally (without break):
# With normal termination
for i in range(3):
print(i)
else:
print("Finished!")
# 0 1 2 Finished!
# With break
for i in range(5):
if i == 3:
break
print(i)
else:
print("Finished!") # Doesn't execute!
# 0 1 2
Application - search:
numbers = [1, 3, 5, 7, 9]
target = 5
for number in numbers:
if number == target:
print(f"Found: {number}")
break
else:
print("Not found")
# Found: 5
Nested Loops
for i in range(3):
for j in range(3):
print(f"({i}, {j})", end=" ")
print() # New line
# (0, 0) (0, 1) (0, 2)
# (1, 0) (1, 1) (1, 2)
# (2, 0) (2, 1) (2, 2)
Multiplication table:
for i in range(1, 6):
for j in range(1, 6):
print(f"{i*j:3}", end=" ")
print()
# 1 2 3 4 5
# 2 4 6 8 10
# 3 6 9 12 15
# 4 8 12 16 20
# 5 10 15 20 25
Simultaneous Iteration with zip
names = ["Ana", "Bob", "Chris"]
ages = [20, 25, 30]
for n, a in zip(names, ages):
print(f"{n} is {a} years old")
# Ana is 20 years old
# Bob is 25 years old
# Chris is 30 years old
Common Patterns
Sum of elements:
numbers = [1, 2, 3, 4, 5]
total = 0
for n in numbers:
total += n
print(total) # 15
# Or simply: sum(numbers)
Finding maximum:
numbers = [3, 7, 2, 9, 5]
maximum = numbers[0]
for n in numbers[1:]:
if n > maximum:
maximum = n
print(maximum) # 9
# Or simply: max(numbers)
Filtering:
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = []
for n in numbers:
if n % 2 == 0:
evens.append(n)
print(evens) # [2, 4, 6, 8, 10]
Common Mistakes
1. Modifying list during iteration
# WRONG - unpredictable behavior!
lst = [1, 2, 3, 4, 5]
for x in lst:
if x % 2 == 0:
lst.remove(x)
# CORRECT - iterate through a copy
for x in lst[:]:
if x % 2 == 0:
lst.remove(x)
2. Confusion with range
# range(5) = 0,1,2,3,4 (doesn't include 5!)
for i in range(5):
print(i) # 0 1 2 3 4
# For 1-5:
for i in range(1, 6):
print(i) # 1 2 3 4 5
3. Not using enumerate
# Inefficient
for i in range(len(lst)):
print(i, lst[i])
# Better
for i, elem in enumerate(lst):
print(i, elem)
Key Points for Exam
range(n)generates 0 to n-1range(a, b)generates a to b-1range(a, b, step)with step (can be negative)enumerate()for index + elementzip()for parallel iterationbreakexits,continueskipselsewith for executes without break- Don’t modify list during iteration!
Review Questions
- What does
list(range(2, 8, 2))display? - When does the
elseblock execute in for? - How do you iterate with both index and element?
- What happens if you modify a list during iteration?