⚡ Phase 2 · Control Flow 🟢 Beginner MODULE 07

For & While Loops

⏱️ 40 min read
📖 Theory + Code
🧩 5 Quiz Questions
🏗️ 1 Challenge
Phase 2 progress33%
🎯 What you'll learn: The two types of Python loops — for (iterate over sequences) and while (repeat while condition is true). The range() function in depth. Loop control with break, continue, and pass. Nested loops, enumerate(), zip(), and the loop-else clause.

Two Types of Loops

Loops let your program repeat a block of code without you having to write it multiple times. Python has exactly two loop types — each suited to different situations.

🔁
for loop
Iterates over a sequence — a list, string, range, tuple, or any iterable. You know in advance how many times it will run.
Use when: you have a collection to process, or a fixed number of repetitions
🔄
while loop
Repeats as long as a condition is True. You may not know how many iterations you'll need before starting.
Use when: you're waiting for user input, a file, or any condition to change

The for Loop

A for loop steps through each item in a sequence one by one, assigning it to a variable you name. When the sequence is exhausted, the loop ends automatically.

for_basics.py
PYTHON
# Looping over a list
fruits = ["apple", "banana", "mango"]
for fruit in fruits:
    print(f"I like {fruit}")
# I like apple
# I like banana
# I like mango

# Looping over a string (character by character)
for char in "Python":
    print(char, end="-")        # P-y-t-h-o-n-
print()  # newline

# Summing numbers in a list
marks = [85, 72, 91, 68, 77]
total = 0
for mark in marks:
    total += mark
print(f"Total: {total}, Average: {total/len(marks):.1f}")
# Total: 393, Average: 78.6

# Loop variable scope — it persists after the loop
for i in [10, 20, 30]:
    pass
print(i)  # 30 — last value assigned

The range() Function

range() generates a sequence of numbers on demand — without storing them all in memory. It's the most common companion to for loops when you need a counter.

CallGeneratesDescription
range(5)0, 1, 2, 3, 40 up to (not including) 5
range(1, 6)1, 2, 3, 4, 5start=1, stop=6 (exclusive)
range(0, 10, 2)0, 2, 4, 6, 8step=2 (every other)
range(10, 0, -1)10, 9, 8, …, 1countdown (negative step)
range(0, 0)(empty)start == stop → no iterations
range_loop.py
PYTHON
# Print 1 to 5
for i in range(1, 6):
    print(i, end=" ")   # 1 2 3 4 5
print()

# Countdown from 5
for i in range(5, 0, -1):
    print(i, end=" ")   # 5 4 3 2 1
print("🚀")

# Sum of 1 to 100
total = 0
for n in range(1, 101):
    total += n
print(total)   # 5050

# Times table
n = 7
for i in range(1, 11):
    print(f"{n} × {i:2} = {n*i:3}")

The while Loop

A while loop repeats its body as long as its condition remains True. The condition is checked before each iteration — if it's already False at the start, the body never runs.

Critical: Something inside the loop must eventually make the condition False, or the loop runs forever (an infinite loop). Always ensure your while condition will eventually become false.

while_loop.py
PYTHON
# Basic while
count = 1
while count <= 5:
    print(count, end=" ")
    count += 1         # ← MUST update or infinite loop!
# 1 2 3 4 5

# Keep asking until valid input — very common pattern
age = -1
while age < 0 or age > 120:
    age = int(input("Enter valid age (0-120): "))
    if age < 0 or age > 120:
        print("  ❌ Invalid. Try again.")
print(f"Age accepted: {age}")

# PIN retry system — limited attempts
CORRECT  = 1234
attempts = 0
MAX      = 3
while attempts < MAX:
    pin = int(input(f"PIN (attempt {attempts+1}/{MAX}): "))
    attempts += 1
    if pin == CORRECT:
        print("✅ Access granted!")
        break
else:
    print("🔒 Account locked.")    # only runs if loop ended without break
⚠️
Avoid infinite loops
If your while loop never ends, press Ctrl+C in the terminal to stop it. Common causes: forgetting to update the loop variable (count += 1), or a condition that can never become False. Always ask: "what will eventually make this False?"

Loop Control — break, continue, pass

Three special keywords give you fine-grained control over loop execution.

break
Exits the loop immediately. Code after the loop continues running.
continue
Skips the rest of the current iteration and jumps to the next one.
pass
Does nothing. A placeholder for an empty block that must have a body.
break_continue_pass.py
PYTHON
# break — exit loop early
numbers = [3, 7, 12, 5, 9]
for n in numbers:
    if n % 2 == 0:
        print(f"First even number: {n}")
        break              # found it — stop searching
# First even number: 12

# continue — skip current iteration
for i in range(1, 11):
    if i % 2 == 0:
        continue           # skip even numbers
    print(i, end=" ")    # 1 3 5 7 9
print()

# pass — empty placeholder
for i in range(5):
    if i == 3:
        pass               # TODO: handle this case later
    print(i, end=" ")    # 0 1 2 3 4  (pass does nothing)

# Loop-else: else runs only if loop completed without break
target = 99
for n in [10, 20, 30]:
    if n == target:
        print("Found!")
        break
else:
    print("Not found in list.")   # runs — no break triggered
Loop-else is a hidden Python gem
Python's for/while loops can have an else clause. It runs only if the loop finished without hitting a break. This is perfect for search operations: the else means "not found". Most Python developers don't know this exists — knowing it sets you apart.

enumerate() & zip()

Two built-in functions that make for loops dramatically more powerful and Pythonic — eliminating the need for manual counter variables.

enumerate_zip.py
PYTHON
# enumerate() — loop with an automatic counter
fruits = ["apple", "banana", "mango"]

# Old way (avoid this):
i = 0
for fruit in fruits:
    print(i, fruit); i += 1

# Pythonic way with enumerate:
for idx, fruit in enumerate(fruits):
    print(f"{idx}: {fruit}")
# 0: apple   1: banana   2: mango

# enumerate with custom start
for num, fruit in enumerate(fruits, start=1):
    print(f"{num}. {fruit}")
# 1. apple   2. banana   3. mango

# ──────────────────────────────────────────────
# zip() — loop over two lists simultaneously
names  = ["Ali", "Sara", "Zara"]
scores = [88, 95, 72]

for name, score in zip(names, scores):
    grade = "A" if score >= 80 else "B"
    print(f"{name:8} {score}  Grade: {grade}")
# Ali       88  Grade: A
# Sara      95  Grade: A
# Zara      72  Grade: B

Nested Loops

A loop inside another loop is called a nested loop. The inner loop runs completely for each single iteration of the outer loop. Nested loops are essential for working with grids, tables, matrices, and patterns.

nested_loops.py
PYTHON
# Multiplication grid
for row in range(1, 4):
    for col in range(1, 4):
        print(f"{row*col:3}", end="")
    print()
#   1  2  3
#   2  4  6
#   3  6  9

# Star pattern
for i in range(1, 6):
    print("★" * i)
# ★
# ★★
# ★★★
# ★★★★
# ★★★★★

# Nested loop with break — search a 2D grid
grid = [[1,2,3],[4,5,6],[7,8,9]]
target = 5
for row_idx, row in enumerate(grid):
    for col_idx, val in enumerate(row):
        if val == target:
            print(f"Found {target} at row {row_idx}, col {col_idx}")
            break          # breaks inner loop only
# Found 5 at row 1, col 1
💡
break only exits the innermost loop
In nested loops, break only exits the loop it's directly inside — not the outer loop. To exit both, you can use a flag variable (found = True; break then check if found: break in outer loop) or wrap in a function and use return.

Choosing: for vs while

🔁
Use for when
You know the collection or count in advance. Iterating a list, string, dict. Running exactly N times with range(N).
🔄
Use while when
You don't know how many iterations needed. Waiting for valid user input. Retrying until success. Game loops. Polling.
⚠️
Infinite loop safety
Always ensure the condition can become False. Add a max-attempts counter to while loops that depend on user input to prevent endless loops in production.
🐍
Pythonic preference
Python strongly favours for loops over while when iterating. If you catch yourself doing i=0; while i < len(lst), switch to for item in lst.
🧩 Knowledge Check
5 questions — test your mastery of Python Loops
1. What does range(2, 10, 3) generate?
2. What does continue do inside a loop?
3. What does enumerate(["a","b","c"], start=1) yield on the first iteration?
4. When does the else clause of a for loop execute?
5. How many times does the inner loop run in total?
for i in range(3):
    for j in range(4):
        print(i, j)
🏗️
Coding Challenge — Number Analysis Engine
Combine for loops, while, break, continue, and enumerate
Task: Build a number analysis program that:

1. Uses a while loop to keep asking the user for numbers until they type done
2. Stores valid numbers in a list; skips non-numeric entries using continue
3. After collecting numbers, uses a for loop with enumerate to print each number with its position
4. Calculates and prints: total, average, maximum, minimum, and count of even numbers
5. Uses a for-else to check if any number is greater than 100 (print "Found!" or "None above 100")
6. Prints all numbers in reverse order using range with a negative step
💡 Show hints
  • Use entry.replace('.','',1).isdigit() to check if a string is a valid number
  • numbers = [] starts an empty list; use numbers.append(val) to add
  • Reverse: for i in range(len(numbers)-1, -1, -1)
  • Even count: use continue for odds, or sum(1 for n in numbers if n%2==0)
number_analysis.py — Sample Solution
PYTHON
# ── Number Analysis Engine ────────────────────
numbers = []

print("Enter numbers one by one. Type 'done' to finish.")
while True:
    entry = input("Number: ").strip()
    if entry.lower() == "done":
        break
    if not entry.replace(".", "", 1).lstrip("-").isdigit():
        print("  ❌ Not a number — skipping.")
        continue
    numbers.append(float(entry))

if not numbers:
    print("No numbers entered.")
else:
    print(f"\n{'─'*34}")
    # Print with position
    for idx, n in enumerate(numbers, 1):
        print(f"  {idx}. {n:g}")

    # Statistics
    total  = sum(numbers)
    avg    = total / len(numbers)
    evens  = sum(1 for n in numbers if n % 2 == 0)
    print(f"\n  Count   : {len(numbers)}")
    print(f"  Total   : {total:g}")
    print(f"  Average : {avg:.2f}")
    print(f"  Max     : {max(numbers):g}")
    print(f"  Min     : {min(numbers):g}")
    print(f"  Evens   : {evens}")

    # For-else: check for > 100
    for n in numbers:
        if n > 100:
            print(f"  Found number > 100: {n:g}")
            break
    else:
        print("  None above 100.")

    # Reverse print
    print("  Reversed:", end=" ")
    for i in range(len(numbers) - 1, -1, -1):
        print(numbers[i], end=" ")
🎉
Lesson 7 Complete!
Loops mastered! Your programs can now repeat, iterate, and process collections of any size. Next — Lists & Tuples!
← Course Home
Phase 2 · Control FlowLesson 7 of 6