Learn Python / For Loops

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!")
Output

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)
Output

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)
Output

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}")
Output

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}")
Output

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)
Output

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")
Output

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}")
Output

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}")
Output

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")
Output

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)
Output

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)
Output
for n in range(1, 11):
    if n % 3 == 0:
        continue      # skip multiples of 3
    print(n, end=" ")
Output
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")
Output

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")
Output

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 row
Output
Going 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!
Output

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)
Output

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
Output

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
Output

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"]
Output

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}
Output

Summary

  • for item in collection: runs the body once for each item.
  • range(start, stop, step) produces numbers. stop is not included.
  • Build results by updating a variable (total += x) or a list (append) inside the loop.
  • enumerate() gives index and item, and zip() walks several lists together.
  • Loop over a dictionary's .items() to get keys and values.
  • break exits the loop, and continue skips to the next pass.