A loop is a way of making a computer repeat an action — without writing that action out over and over again. Loops are one of the most powerful ideas in programming: they let a program process ten items or ten million items with the same few lines of code. Python has two kinds of loop, each suited to a different situation: the <strong>while</strong> loop repeats as long as a condition is true, and the <strong>for</strong> loop steps through a collection one item at a time.
1 Why Do We Need Loops?
Suppose you want to print a countdown from 5 to 1. You could write it out by hand:
print(5)
print(4)
print(3)
print(2)
print(1)
print("Liftoff!")That works for five numbers. But what if you needed a countdown from 1,000? Or if you had a list of 500 student names to process? Writing one line per item is not programming — it is just typing. Loops solve this.
The instructions on a shampoo bottle say: "Lather, rinse, repeat." They do not say: "Lather, rinse. Now lather again, rinse again. Now lather a third time..." A loop is the "repeat" instruction. You describe the action once, and the computer carries it out as many times as needed.
Here is the same countdown written with a loop — it will work whether the starting number is 5 or 5,000:
n = 5
while n > 0:
print(n)
n -= 1
print("Liftoff!")2 The while Loop
A while loop keeps running its body as long as a condition is True. Every time Python reaches the bottom of the loop body, it jumps back to the top and checks the condition again. When the condition becomes False, the loop stops and Python moves on to whatever comes next.
2.1 The Structure
while condition:
# body: runs repeatedly as long as condition is TrueThe rules are the same as for if statements: a colon after the condition, and the body indented. The critical difference is that an if runs its body at most once. A while loop can run its body thousands of times.
A vending machine keeps accepting coins while the balance is less than the item price. Each coin inserted increases the balance, and the machine checks again. The moment the balance reaches the price, the loop ends and the item is dispensed. Something inside the loop (inserting a coin) changes the state so that the condition eventually becomes false. That change is essential — without it, the loop runs forever.
2.2 A Full Example with Trace
count = 1
while count <= 4:
print("Count is:", count)
count += 1
print("Done.")Let's trace this execution step by step — this is called a loop trace. Good programmers do this on paper before running unfamiliar loops:
| Iteration | count (at top) | Condition: count <= 4 | Loop runs? | Printed | count (at bottom) |
|---|---|---|---|---|---|
| 1 | 1 | 1 <= 4 → True | Yes | Count is: 1 | 2 |
| 2 | 2 | 2 <= 4 → True | Yes | Count is: 2 | 3 |
| 3 | 3 | 3 <= 4 → True | Yes | Count is: 3 | 4 |
| 4 | 4 | 4 <= 4 → True | Yes | Count is: 4 | 5 |
| — | 5 | 5 <= 4 → False | No — exit loop | — | — |
After the loop exits, Python prints "Done." — that line is outside the loop (not indented under while), so it runs exactly once.
2.3 The Infinite Loop — and How to Avoid It
The most dangerous mistake with a while loop is writing one where the condition never becomes False. This is called an infinite loop — the program runs forever and never moves on:
# DANGER: infinite loop — count never changes, condition never becomes False
count = 1
while count <= 4:
print("Count is:", count)
# forgot count += 1 !Every while loop needs something inside it that changes the state so the condition can eventually become False. Before you write a while loop, always ask: "What will make this condition false, and does my loop actually do that?"
If you run a program and it just sits there producing output endlessly (or nothing at all), press Ctrl + C in the terminal to interrupt it. Then look for the while loop that has no way out. The fix is almost always a missing update to the variable that the condition checks.
2.4 A Practical while Loop: Input Validation
One of the most common real uses of a while loop is asking the user for input repeatedly until they give a valid answer. This is called an input validation loop:
age = int(input("Enter your age: "))
while age < 0 or age > 120:
print("That does not look like a valid age. Please try again.")
age = int(input("Enter your age: "))
print("Thank you! Age recorded:", age)The loop keeps running as long as the input is invalid. The moment a valid age is entered, the condition becomes False and the loop exits cleanly. This pattern — keep asking until the answer is acceptable — is something you will use constantly.
- What is the key difference between a
whileloop and anifstatement — even though they both use a condition? Trace this loop on paper. Fill in the value of
xat the start of each iteration, and write down what is printed.x = 10 while x > 0: print(x) x -= 3A student writes this loop. What goes wrong? How do you fix it?
lives = 3 while lives > 0: print("Lives remaining:", lives)- Write a
whileloop that asks the user to enter a password, and keeps asking until they enter"open sesame". How many times does this loop run? Trace it to find out.
n = 1 while n < 100: n *= 2 print(n)
3 The for Loop
A for loop steps through a sequence — a list, a range of numbers, or a string — one item at a time. For each item, it runs the loop body once. When there are no more items, the loop ends automatically.
Unlike a while loop, a for loop has a built-in stopping point: the end of the sequence. You do not need to worry about updating a counter or creating an infinite loop.
A teacher calls the class register: they go through the list of names one by one, calling each name in turn. They do not need to track what number they are on — they just move to the next name until the list is finished. A for loop works exactly this way: it moves through a sequence, handling each item, and stops naturally when the list runs out.
3.1 The Structure
for variable in sequence:
# body: runs once for each item in the sequenceThe variable is a new name that holds the current item in each iteration. You choose the name — pick something descriptive. The sequence is whatever you are stepping through.
3.2 Looping Over a List
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)Output:
apple banana cherry
On the first iteration, fruit is "apple". On the second, it is "banana". On the third, "cherry". After that, the list is exhausted and the loop ends.
3.3 Looping Over a String
A string is also a sequence — a sequence of characters. A for loop will step through each character one at a time:
word = "Python"
for letter in word:
print(letter)Output:
P y t h o n
3.4 Combining Loops and Conditionals
Loops and conditionals work naturally together. Here a loop steps through a list and a conditional picks out only certain items:
scores = [85, 42, 91, 67, 55, 78, 39, 95]
print("Students who need extra support:")
for score in scores:
if score < 60:
print(" -", score)The loop visits all eight scores; the if inside it only prints the ones below 60. This pattern — loop through everything, act on some — is one of the most useful in programming.
- How does a
forloop know when to stop? Compare this to how awhileloop stops. Predict the output of this program:
animals = ["cat", "dog", "fish", "bird"] for animal in animals: print("I have a", animal)- Write a
forloop that prints every letter in the string"hello"on its own line. What is printed by this program? Trace it carefully:
numbers = [3, 7, 2, 9, 4, 6] total = 0 for n in numbers: total += n print("Total:", total)- Write a loop that goes through a list of names and prints only those that start with the letter
"A". (Hint: usename[0]to get the first character, orname.startswith("A").)
4 Counting with range()
Very often you want to loop a specific number of times, or step through a range of numbers, without having to create a list yourself. Python's built-in range() function generates a sequence of numbers for you — and works perfectly with a for loop.
4.1 Three Forms of range()
| Form | What it generates | Example | Numbers produced |
|---|---|---|---|
range(stop) | Numbers from 0 up to (but not including) stop. | range(5) | 0, 1, 2, 3, 4 |
range(start, stop) | Numbers from start up to (but not including) stop. | range(1, 6) | 1, 2, 3, 4, 5 |
range(start, stop, step) | Numbers from start to stop, jumping by step each time. | range(0, 10, 2) | 0, 2, 4, 6, 8 |
range(5) gives you 0, 1, 2, 3, 4 — it stops before 5. This catches almost every beginner off-guard. To loop from 1 to 5 inclusive, write range(1, 6). A helpful way to remember: the stop value is the first number not included.
4.2 range() in Action
# Print 0 to 4
for i in range(5):
print(i)
# Print 1 to 5
for i in range(1, 6):
print(i)
# Print even numbers from 0 to 10
for i in range(0, 11, 2):
print(i)
# Count backwards from 5 to 1
for i in range(5, 0, -1):
print(i)
print("Liftoff!")By convention, programmers often use i as the loop variable when they only care about the count, not the value itself — it is short for "index". You will see i, j, and k used this way everywhere. If you are looping over something meaningful (a list of names, a list of scores), use a descriptive name instead. If you are just counting repetitions, i is fine.
4.3 Using range() to Repeat an Action
Sometimes you want to run a block of code a fixed number of times and you do not need the loop variable at all. This is completely valid:
# Ask for 3 quiz answers
for i in range(3):
answer = input("Enter your answer: ")
print("Recorded:", answer)Here i is never used inside the loop body — the loop just ensures the block runs exactly 3 times. Some programmers write _ as the variable name in this case (for _ in range(3):) to signal that the variable is intentionally unused. Both styles are fine.
What numbers does each of these produce? Write them out.
range(4) range(2, 7) range(0, 20, 5) range(10, 0, -2)
- A student wants to print the numbers 1 through 10. They write
for i in range(10):. What goes wrong? How do you fix it? - Write a
forloop usingrange()that prints the 5 times table (5, 10, 15, … up to 50). - Write a loop that prints a countdown from 10 to 1, then prints "Go!".
Predict the output:
total = 0 for i in range(1, 6): total += i print(total)
5 Choosing Between while and for
Knowing which loop to use is an important design skill. Here is the core rule:
Use for when… | Use while when… |
|---|---|
| You know exactly how many times to loop, or you are stepping through a sequence. | You do not know how many times you will loop — it depends on something that happens at runtime. |
You have a list, string, or range() to iterate over. | You are waiting for a condition to change — user input, a game state, a sensor reading. |
| "Do this for each item in the collection." | "Keep doing this until something changes." |
| Examples: process every score in a list; print a times table; step through each character in a string. | Examples: keep asking until valid input; run a game until the player loses; retry until a connection succeeds. |
Ask yourself: "Do I know the number of repetitions before the loop starts?" If yes — for. If no — while. For example: "Print 10 lines" → you know the count → for. "Keep asking until the user types 'quit'" → you do not know how many tries they will need → while.
6 Controlling a Loop: break and continue
Python gives you two keywords that let you take control of a loop from inside its body. Both work in for and while loops.
6.1 break — Exit the Loop Early
break immediately stops the loop and jumps to the first line after it — no matter what the condition says or how many items are left in the sequence.
Imagine searching a building for someone. You check each room in turn. The moment you find them, you stop searching and leave — you do not finish checking every remaining room just because the building has more floors. break is that "found it — stop now" instruction.
names = ["Alice", "Ben", "Carol", "Dan", "Eve"]
target = "Carol"
for name in names:
if name == target:
print("Found:", name)
break
print("Checking:", name)
print("Search complete.")Output:
Checking: Alice Checking: Ben Found: Carol Search complete.
Once "Carol" is found, break exits the loop immediately. "Dan" and "Eve" are never checked.
6.2 continue — Skip to the Next Iteration
continue skips the rest of the current iteration and jumps straight back to the top of the loop to start the next one. It does not exit the loop — it just skips one pass.
Imagine a playlist shuffling through songs. When a song you dislike comes on, you hit skip — the song ends early and the next one starts immediately. You have not stopped the playlist; you have just skipped one item. continue does the same thing: skip this item, carry on with the rest.
scores = [85, -1, 42, -1, 91, 67]
print("Valid scores:")
for score in scores:
if score < 0:
continue # skip invalid entries
print(score)Output:
Valid scores: 85 42 91 67
The -1 entries are skipped; the loop continues normally for all other values.
6.3 break and continue in while Loops
Both keywords work in while loops too. A common pattern is a while True: loop — one that would run forever on its own — controlled entirely by a break:
# A menu that keeps running until the user chooses to quit
while True:
choice = input("Enter command (help / quit): ").lower()
if choice == "quit":
print("Goodbye!")
break
elif choice == "help":
print("Available commands: help, quit")
else:
print("Unknown command. Try 'help'.")while True: creates an intentional infinite loop. The only way out is the break when the user types "quit". This is a widely used and perfectly acceptable pattern — as long as there is a clear, reachable break inside.
Used well, break and continue make code clearer. Used carelessly, they make loops hard to trace and debug because execution jumps around unexpectedly. Before reaching for break, ask: could I restructure the condition to stop the loop naturally instead? Before reaching for continue, ask: could I just wrap the body in an <i>if</i> statement instead? Often the answer is yes — and the result is simpler code.
- What is the difference between
breakandcontinue? Use a one-sentence analogy for each. Predict the output of this program:
for i in range(1, 8): if i == 4: continue if i == 6: break print(i)- Why is
while True:not automatically a mistake? What makes it safe to use? Rewrite this code to use
continueinstead of nesting:for word in ["cat", "", "dog", "", "fish"]: if len(word) > 0: print(word.upper())- Write a loop using
while Trueandbreakthat keeps asking the user to guess a number between 1 and 10, and stops when they guess correctly (the answer is 7).
7 Common Loop Patterns
Certain loop structures appear so frequently in real programs that they are worth learning by name. Once you recognise these patterns, you will be able to write them from memory and spot them instantly in other people's code.
7.1 The Accumulator Pattern
Create a variable before the loop. Update it inside the loop. Read the result after the loop.
# Sum all numbers in a list
scores = [78, 92, 55, 84, 67]
total = 0 # accumulator starts at 0
for score in scores:
total += score # add each score to the running total
print("Total:", total)
print("Average:", total / len(scores))7.2 The Counter Pattern
Count how many items in a sequence meet a condition.
scores = [78, 92, 55, 84, 40, 67, 38]
passing = 0 # counter starts at 0
for score in scores:
if score >= 60:
passing += 1 # increment when condition is met
print(passing, "students passed out of", len(scores))7.3 The Search Pattern
Loop through a sequence and stop as soon as you find what you are looking for.
usernames = ["alice", "bob", "carol", "dan"]
search = "carol"
found = False
for name in usernames:
if name == search:
found = True
break
if found:
print(search, "exists in the system.")
else:
print(search, "was not found.")7.4 The Collector Pattern
Build a new list by collecting only the items that meet a condition.
scores = [78, 92, 55, 84, 40, 67, 38]
high_scores = [] # start with an empty list
for score in scores:
if score >= 80:
high_scores.append(score) # add qualifying scores
print("High scores:", high_scores)7.5 The Input-Until-Valid Pattern
Keep asking the user for input until they provide something acceptable.
while True:
response = input("Type yes or no: ").lower()
if response == "yes" or response == "no":
break
print("Please type exactly 'yes' or 'no'.")
print("You chose:", response)You will mix and combine these patterns constantly. A single loop might accumulate a total, count a subset, and collect results all at once. Knowing the patterns by name gives you a vocabulary to think and talk about code — and a starting point when you are not sure how to begin.
8 Putting It All Together
Here is a complete program that uses both types of loops, range(), break, and three of the patterns above. Read it carefully and trace the execution before looking at the explanation below.
PASSING_SCORE = 60
NUM_STUDENTS = 4
scores = []
total = 0
failing = []
# Input loop — collect scores from the user
print("--- Score Entry ---")
for i in range(1, NUM_STUDENTS + 1):
while True:
score = int(input(f"Enter score for student {i} (0–100): "))
if 0 <= score <= 100:
break
print("Invalid score. Please enter a number between 0 and 100.")
scores.append(score)
# Processing loop — analyse the collected scores
for score in scores:
total += score # accumulator
if score < PASSING_SCORE:
failing.append(score) # collector
average = total / len(scores)
# Results
print("\n--- Results ---")
print("Scores entered:", scores)
print(f"Average score: {average:.1f}")
print(f"Students failing ({len(failing)}):", failing)
if len(failing) == 0:
print("All students passed!")What this program demonstrates:
- A
<strong>for</strong>loop overrange()controls how many students are entered. - A
<strong>while True</strong>loop inside theforloop validates each entry — a loop inside a loop, called a nested loop. - The accumulator pattern builds the total; the collector pattern gathers failing scores.
breakexits the innerwhileloop the moment a valid score is entered.- All processing happens in a single pass through the list — one loop, three things happening at once.
9 Final Check: The Big Picture
A <strong>while</strong> loop repeats as long as a condition is true — use it when you do not know how many iterations you will need. A <strong>for</strong> loop steps through a sequence — use it when you are iterating over a collection or a known range. <strong>range()</strong> generates number sequences for counting. <strong>break</strong> exits a loop early; <strong>continue</strong> skips the rest of the current iteration. The accumulator, counter, search, and collector patterns appear in almost every real program you will ever write.
- Explain in plain English when you would choose a
forloop over awhileloop, and vice versa. Give a real-world example of each. Trace this program completely. Write the value of every variable at the end of each iteration.
result = 1 for i in range(1, 5): result *= i print(result)This program has a bug that will cause it to crash on some inputs. Find it and fix it.
numbers = [10, 0, 5, 0, 2] for n in numbers: print(100 / n)- Write a program that asks the user to enter 5 numbers one at a time, then prints the largest number entered. Do not use Python's built-in
max()function — track the largest value yourself inside the loop. What is the output of this program? Trace it step by step.
words = ["apple", "ant", "banana", "avocado", "cherry"] count = 0 for word in words: if word.startswith("a"): count += 1 if count == 2: break print("Found", count, "words starting with 'a' before stopping.")A student wants to print every odd number from 1 to 19. They write:
for i in range(1, 20): if i % 2 == 0: continue print(i)This works — but write a version using
range()with a step argument that does not needcontinueat all. Which version do you think is clearer?
10 Quick-Reference Summary
| Concept | Syntax | Key rule / use case |
|---|---|---|
while loop | while condition: | Runs as long as condition is True. Must change state to avoid infinite loop. |
for loop | for item in sequence: | Steps through a sequence one item at a time. Stops automatically. |
range(stop) | range(5) → 0,1,2,3,4 | Generates numbers from 0 up to (not including) stop. |
range(start, stop) | range(1, 6) → 1,2,3,4,5 | Generates numbers from start up to (not including) stop. |
range(start, stop, step) | range(0, 10, 2) → 0,2,4,6,8 | Jumps by step each time. Use negative step to count down. |
break | break | Exits the loop immediately. Works in both for and while. |
continue | continue | Skips the rest of the current iteration and starts the next one. |
| Accumulator | total = 0 … total += x | Build a running total or combined result across all iterations. |
| Counter | count = 0 … count += 1 | Count how many items meet a condition. |
| Search | Loop + if … break | Find the first item that matches; stop as soon as it is found. |
| Collector | result = [] … result.append(x) | Build a new list of items that meet a condition. |