Why Loops Matter
Many programs need to do the same kind of work more than once: process a list of items, retry an action until it succeeds, count occurrences, or generate repeated output. Writing the same lines of code over and over is slow, error-prone, and hard to change later. Loops solve this by letting you repeat actions in a controlled way.
In Python, the two main loop types are for loops (repeat for each item in a sequence) and while loops (repeat while a condition stays true). On top of that, there are common iteration patterns—like counting, accumulating totals, searching, and building new collections—that show up in many small useful scripts.
The for Loop: Repeating for Each Item
A for loop is used when you have a collection of items (or something that produces items) and you want to run the same block of code once per item.
Basic structure
for item in sequence:
# do something with itemThe loop variable (item) takes on each value from the sequence, one at a time. The indented block runs once per value.
Example: printing each name
names = ["Ava", "Ben", "Chloe"]
for name in names:
print("Hello,", name)This pattern is ideal for “do something to every element.”
Continue in our app.
You can listen to the audiobook with the screen off, receive a free certificate for this course, and also have access to 5,000 other free online courses.
Or continue reading below...Download the app
Step-by-step: how the loop runs
- Python takes the first element (
"Ava"), assigns it toname, runs the block. - Then it takes the next element (
"Ben"), assigns it toname, runs the block again. - Then
"Chloe", and so on. - When there are no more elements, the loop ends and execution continues after the loop.
Iterating Over Common Built-ins
Looping over a string (character by character)
word = "python"
for ch in word:
print(ch)This is useful for tasks like counting letters or checking whether a string contains only certain characters.
Looping over a dictionary
Dictionaries can be iterated in several ways depending on what you need: keys, values, or key-value pairs.
prices = {"apple": 0.80, "banana": 0.50, "orange": 0.90}
for fruit in prices: # keys by default
print(fruit)
for cost in prices.values():
print(cost)
for fruit, cost in prices.items():
print(fruit, "costs", cost)The .items() pattern is especially common when you need both the key and the value.
Counting with range()
Sometimes you don’t have a list of items, but you want to repeat something a specific number of times. Python’s range() generates a sequence of integers.
Repeat N times
for i in range(5):
print("Iteration", i)This runs 5 times with i taking values 0, 1, 2, 3, 4. If you want a human-friendly count starting at 1, you can shift it.
for i in range(1, 6):
print("Step", i)Using a step value
for n in range(0, 11, 2):
print(n) # 0, 2, 4, 6, 8, 10range(start, stop, step) is a powerful way to generate counting patterns without manually updating a counter.
The while Loop: Repeat Until Something Changes
A while loop repeats as long as its condition is true. It’s best when you don’t know in advance how many iterations you need, such as reading input until the user types a sentinel value, retrying an operation, or looping until a goal is reached.
Basic structure
while condition:
# do something
# update something so the loop can eventually endThe key idea is that something inside the loop must change so the condition eventually becomes false. If not, you create an infinite loop.
Example: keep asking until a non-empty value
name = ""
while name == "":
name = input("Enter your name: ").strip()
print("Hi,", name)Here, the loop continues until name is not empty. The .strip() removes spaces so that input like " " is treated as empty.
Step-by-step: preventing infinite loops
- Start with a value that makes the condition true (
name = ""). - Inside the loop, update the variable (
name = input(...)). - On the next check, if the condition is now false, the loop ends.
Loop Control: break and continue
Python provides two keywords to control loop flow.
break: exit the loop immediately
numbers = [3, 7, 2, 9, 5]
for n in numbers:
if n == 2:
break
print(n)This prints 3 and 7, then stops when it reaches 2.
continue: skip to the next iteration
numbers = [3, 7, 2, 9, 5]
for n in numbers:
if n % 2 == 0:
continue
print(n)This prints only odd numbers. When an even number is found, the loop skips the remaining code in the block and moves on.
Common Iteration Patterns (Used in Real Scripts)
Learning loops is easier when you recognize patterns. These patterns are building blocks for many practical programs.
Pattern 1: Counting items that match a rule
Goal: count how many values satisfy a condition.
temps = [18, 21, 25, 19, 30, 16]
count_hot = 0
for t in temps:
if t >= 25:
count_hot += 1
print("Hot days:", count_hot)Key idea: initialize a counter to 0, then increase it when the rule matches.
Pattern 2: Accumulating a total (sum)
Goal: compute a total from many values.
expenses = [12.50, 3.20, 18.00, 6.75]
total = 0
for cost in expenses:
total += cost
print("Total:", total)This is the same structure as counting, but you add the value instead of adding 1.
Pattern 3: Finding a maximum or minimum
Goal: find the largest (or smallest) value.
scores = [88, 91, 75, 99, 84]
best = scores[0]
for s in scores:
if s > best:
best = s
print("Best score:", best)Important detail: you need a sensible starting value. A common approach is to start with the first element.
Pattern 4: Searching for an item
Goal: determine whether a target exists, and possibly stop early.
emails = ["a@example.com", "b@example.com", "c@example.com"]
target = "b@example.com"
found = False
for e in emails:
if e == target:
found = True
break
print("Found?", found)Using break avoids unnecessary work once the item is found.
Pattern 5: Building a new list (filtering)
Goal: create a list containing only items you want.
numbers = [1, 2, 3, 4, 5, 6]
evens = []
for n in numbers:
if n % 2 == 0:
evens.append(n)
print(evens)This pattern shows up in scripts that clean data, select files, or extract values.
Pattern 6: Transforming items (mapping)
Goal: create a new list where each item is changed in some way.
prices = [10, 20, 30]
with_tax = []
for p in prices:
with_tax.append(p * 1.2)
print(with_tax)Filtering keeps some items; mapping changes all items.
Working with Indexes: enumerate()
Sometimes you need both the item and its position (index). You could use range(len(...)), but Python provides enumerate() which is clearer.
tasks = ["email client", "write report", "backup files"]
for i, task in enumerate(tasks, start=1):
print(i, "-", task)This prints a numbered list starting at 1. The start argument is optional.
Looping Over Two Lists Together: zip()
When you have two lists that line up item-by-item (like names and scores), zip() lets you iterate over pairs.
names = ["Ava", "Ben", "Chloe"]
scores = [88, 91, 75]
for name, score in zip(names, scores):
print(name, "scored", score)zip() stops when the shortest input runs out, which is usually what you want when pairing aligned data.
Nested Loops: Loops Inside Loops
A nested loop is a loop inside another loop. This is useful for working with grids, tables, or combinations of items. Be careful: nested loops can grow the amount of work quickly.
Example: simple multiplication table
for row in range(1, 4):
for col in range(1, 4):
print(row * col, end=" ")
print()The inner loop runs fully for each iteration of the outer loop. The end=" " argument keeps values on the same line, and the final print() moves to the next line after each row.
Sentinel Loops: Repeating Until a Special Value Appears
A sentinel value is a special input that means “stop.” This is a common pattern in small scripts that accept repeated input.
Step-by-step: building a running total until the user types done
total = 0
while True:
text = input("Enter an amount (or 'done'): ").strip().lower()
if text == "done":
break
amount = float(text)
total += amount
print("Total:", total)while Truecreates a loop that would run forever.- The sentinel check (
if text == "done": break) provides the exit. - Each valid number is converted and added to
total.
This pattern is practical, but it assumes the user always types a valid number or done. In real scripts, you often add input validation, but the core loop structure stays the same.
Input Validation Loops (Repeat Until Valid)
Another common use of while is to keep asking until the input meets your rules.
Step-by-step: ensure the user enters a positive integer
while True:
text = input("Enter a positive whole number: ").strip()
if text.isdigit() and int(text) > 0:
n = int(text)
break
print("Try again.")
print("You entered:", n)text.isdigit()checks that all characters are digits (no minus sign, no decimal point).- If valid, convert to
intandbreakout of the loop. - If invalid, print a message and repeat.
Off-by-One Errors and Boundaries
When counting or using range(), beginners often run into “off-by-one” mistakes, where a loop runs one time too many or too few. Remember that range(start, stop) includes start but excludes stop.
# Prints 1 through 5
for i in range(1, 6):
print(i)If you accidentally wrote range(1, 5), you would only get 1 through 4.
Choosing Between for and while
Use for when you can describe the work as “for each item in this sequence” or “repeat N times.” Use while when the loop should continue until a condition changes, and you can’t easily predict the number of iterations.
for: processing lists of filenames, iterating through lines of text, repeating a fixed number of steps.while: retrying until valid input, looping until a running total reaches a threshold, repeating until a sentinel value appears.
Mini Script Patterns You Can Reuse
Pattern A: Numbered menu selection loop
This pattern repeats a menu until the user chooses to quit. It combines while, input validation, and branching based on the choice.
while True:
print("1) Add item")
print("2) List items")
print("3) Quit")
choice = input("Choose: ").strip()
if choice == "1":
print("Adding...")
elif choice == "2":
print("Listing...")
elif choice == "3":
break
else:
print("Invalid choice")The loop continues until the user selects the quit option, which triggers break.
Pattern B: Process lines of text and count matches
This shows a realistic “scan and count” loop. Imagine you have a list of lines from a file or pasted text.
lines = [
"ERROR: disk full",
"INFO: started",
"ERROR: permission denied",
"WARNING: low memory"
]
error_count = 0
for line in lines:
if line.startswith("ERROR"):
error_count += 1
print("Errors:", error_count)This is a common pattern in log checking scripts.
Pattern C: Build a cleaned list (strip and ignore blanks)
raw = [" apples ", "", " bananas", " ", "cherries"]
clean = []
for item in raw:
item = item.strip()
if item == "":
continue
clean.append(item)
print(clean)This combines transformation (strip) and filtering (skip blanks).