For Loops
Imagine printing a greeting for 100 students. Writing 100 print() lines would be painful. A loop runs the same block of code over and over, and a for loop runs it once for each item in a collection.
Looping over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(f"I like {fruit}")
print("Done!")Each time round the loop, the variable fruit holds the next item. The indented block is the body of the loop. Like if, the line ends with a colon and the body is indented.
You can name the loop variable anything. Pick a name that describes one item: for student in students, for price in prices.
Looping over a string
A string is a sequence of characters, so you can loop over it too:
for letter in "Python":
print(letter)range(): looping a number of times
range(n) produces the numbers 0 up to, but not including, n:
for i in range(5):
print("Lap", i)range can also take a start and a step:
print(list(range(1, 6))) # 1 to 5
print(list(range(0, 20, 5))) # count in fives
print(list(range(10, 0, -2))) # count down
for n in range(1, 4):
print(f"{n} x 7 = {n * 7}")Building up a result
A very common pattern: start with an empty or zero value, then update it on every pass.
prices = [4.99, 12.50, 3.25, 8.00]
total = 0
for price in prices:
total += price
print(f"Total: {total:.2f}")Here's what happens to total on each pass through the loop:
| Pass | price |
total before |
total after |
|---|---|---|---|
| 1 | 4.99 | 0 | 4.99 |
| 2 | 12.50 | 4.99 | 17.49 |
| 3 | 3.25 | 17.49 | 20.74 |
| 4 | 8.00 | 20.74 | 28.74 |
After the last pass, the loop ends and the print line runs once.
The same idea works for building a new list:
names = ["ada", "grace", "alan"]
capitalized = []
for name in names:
capitalized.append(name.capitalize())
print(capitalized)Using if inside a loop
Combine loops with if to filter or count:
scores = [45, 82, 67, 91, 38, 74]
passed = 0
for score in scores:
if score >= 50:
passed += 1
print(score, "pass")
else:
print(score, "fail")
print(f"{passed} of {len(scores)} passed")enumerate(): position and value together
When you need the position as well as the item, use enumerate(). It gives you (index, item) pairs, which you can unpack right in the for line:
podium = ["Mia", "Leo", "Ava"]
for position, name in enumerate(podium, start=1):
print(f"{position}. {name}")zip(): two lists side by side
zip() pairs up items from two (or more) lists:
names = ["Ada", "Grace", "Alan"]
ages = [36, 85, 41]
for name, age in zip(names, ages):
print(f"{name} is {age}")Looping over a dictionary
Looping over a dictionary gives you its keys. Use .items() to get each key and value together:
stock = {"apples": 12, "pears": 0, "bananas": 7}
for fruit in stock:
print(fruit)
for fruit, count in stock.items():
if count == 0:
print(f"{fruit}: SOLD OUT")
else:
print(f"{fruit}: {count} left")Counting words is a classic use of a loop plus a dictionary:
text = "the cat sat on the mat the end"
counts = {}
for word in text.split():
counts[word] = counts.get(word, 0) + 1
print(counts)break and continue
break stops the loop immediately. continue skips the rest of the current pass and moves on to the next item.
numbers = [3, 8, -1, 12, 5]
for n in numbers:
if n < 0:
print("Found a negative number, stopping.")
break
print(n)for n in range(1, 11):
if n % 3 == 0:
continue # skip multiples of 3
print(n, end=" ")Going deeper: for ... else optional
A for loop can have an else block. It runs only when the loop finishes without hitting break. That makes it a neat fit for searches: did you find what you were looking for, or not?
numbers = [3, 7, 11, 15]
for n in numbers:
if n % 2 == 0:
print("Found an even number:", n)
break
else:
print("No even numbers in the list")Change one of the numbers to an even number and run it again. This time break happens, so the else block is skipped.
Without else, you'd need an extra variable to remember whether you found something:
numbers = [3, 7, 11, 15]
found = False
for n in numbers:
if n % 2 == 0:
found = True
break
if not found:
print("No even numbers in the list")The easiest way to read it is as "no break". The else doesn't mean "if the loop didn't run": looping over an empty list also runs the else block, because nothing called break.
Going deeper: Loops inside loops optional
A loop can contain another loop. The inner loop runs completely for each pass of the outer loop:
for row in range(1, 4):
for col in range(1, 4):
print(row * col, end="\t")
print() # new line after each rowGoing deeper: Don't change a list while looping over it optional
Removing items from a list while a for loop is going through it makes the loop skip items. Here the second 3 survives:
numbers = [1, 3, 3, 4, 5]
for n in numbers:
if n == 3:
numbers.remove(n)
print(numbers) # [1, 3, 4, 5]: one 3 was skipped!When the first 3 is removed, every later item shifts one place to the left, so the loop jumps straight past the second 3. The safe way is to build a new list with the items you want to keep:
numbers = [1, 3, 3, 4, 5]
kept = []
for n in numbers:
if n != 3:
kept.append(n)
print(kept)You'll learn a shorter way to write this in the List Comprehensions lesson.
Exercises
Exercise 1: Countdown
Use a for loop and range() to print 5, 4, 3, 2, 1 on separate lines, then Liftoff!.
# Count down from 5
range() can count down if you give it a negative step.
range(5, 0, -1) gives 5, 4, 3, 2, 1. Print Liftoff! after the loop, not inside it.
Exercise 2: Sum of even numbers
Add up all the even numbers from 1 to 100 (inclusive) and print the total, which is 2550.
total = 0
Loop over range(1, 101) so that 100 is included.
Inside the loop, add n to total only when n % 2 == 0. Print total after the loop.
Exercise 3: Longest word
Find and print the longest word in the list without using max(). It should print elephant.
words = ["cat", "elephant", "dog", "giraffe", "ant"]
Start with longest = "" and check every word in a loop.
If len(word) > len(longest), that word becomes the new longest.
Exercise 4: Shopping receipt
Print each item with its line total, then the grand total. Use .items() to loop over the dictionary.
coffee x 2 = 6.0
muffin x 3 = 7.5
juice x 1 = 4.0
Total: 17.5
prices = {"coffee": 3.0, "muffin": 2.5, "juice": 4.0}
cart = {"coffee": 2, "muffin": 3, "juice": 1}
Loop with for item, quantity in cart.items():.
Inside the loop, multiply prices[item] by quantity, print the line and add it to total. Print the total after the loop.
Summary
for item in collection:runs the body once for each item.range(start, stop, step)produces numbers.stopis not included.- Build results by updating a variable (
total += x) or a list (append) inside the loop. enumerate()gives index and item, andzip()walks several lists together.- Loop over a dictionary's
.items()to get keys and values. breakexits the loop, andcontinueskips to the next pass.