Lesson 5 • Beginner

    Loops: Repeating Code in Python

    Learn how to make Python repeat tasks automatically using for and while loops.

    What You'll Learn in This Lesson

    • How for loops repeat code for each item in a sequence
    • How range() generates number sequences
    • How while loops repeat until a condition changes
    • When to use for vs while
    • How break exits a loop early and continue skips an iteration
    • How to loop through lists, strings, and dictionaries

    What Are Loops?

    Loops let you repeat code multiple times without writing it over and over. Instead of writing print("Hello") 100 times, you can use a loop to do it once.

    Real-world analogy:

    Think of loops like a washing machine cycle. It repeats the same steps (wash, rinse, spin) until the clothes are clean. Your code works the same way!

    Python has two main types of loops:

    for loop

    Use when you know how many times to repeat

    "Do this 10 times" or "Do this for each item"

    while loop

    Use when you repeat until a condition changes

    "Keep asking until user says stop"

    🧠 How Loops Execute: The Mental Model

    Before writing loops, build a clear picture of what Python is actually doing each time through. This mental model prevents most beginner loop bugs.

    The loop variable is reassigned every iteration

    Each time the loop runs, the loop variable gets the next value from the sequence. Python handles this automatically — you just use it.

    The indented block is one "iteration"

    Everything indented under for or while is the loop body. It runs once per value. Code at the original indentation level runs after the loop finishes.

    The loop variable still exists after the loop

    After a for loop finishes, the loop variable holds the last value it had. This is sometimes useful — but can also cause bugs if you forget.

    Trace through this step by step:

    fruits = ["apple", "banana", "cherry"]
    
    for fruit in fruits:
        print(fruit.upper())
    
    print("Done:", fruit)

    Execution trace:

    fruit = "apple" → prints APPLE

    fruit = "banana" → prints BANANA

    fruit = "cherry" → prints CHERRY

    ④ Sequence exhausted → loop exits

    print("Done:", fruit)Done: cherry

    1. The for Loop

    The for loop repeats code for each item in a sequence (like a list or range of numbers).

    # Syntax:

    for variable in sequence:

    code to repeat

    PartDescription
    forKeyword that starts the loop
    variableHolds the current item (you choose the name)
    inKeyword connecting variable to sequence
    sequenceWhat to loop over (list, range, string, etc.)
    :Required colon at the end

    Try It: Basic for Loop

    Loop through items in a list

    Try it Yourself »
    Python
    # Loop through a list
    fruits = ["apple", "banana", "cherry"]
    
    for fruit in fruits:
        print(f"I like {fruit}!")
    
    print("Done with fruits!")
    
    # The variable 'fruit' takes each value in turn:
    # First loop:  fruit = "apple"
    # Second loop: fruit = "banana"
    # Third loop:  fruit = "cherry"

    2. The range() Function

    range() generates a sequence of numbers. It's the most common way to repeat code a specific number of times.

    SyntaxWhat It ProducesExample
    range(stop)0 to stop-1range(5) → 0,1,2,3,4
    range(start, stop)start to stop-1range(2, 6) → 2,3,4,5
    range(start, stop, step)start to stop-1, by steprange(0, 10, 2) → 0,2,4,6,8

    Try It: range() Function

    See different ways to generate number sequences

    Try it Yourself »
    Python
    # Different ways to use range()
    
    # Count 0 to 4
    print("range(5):")
    for i in range(5):
        print(i, end=" ")
    print()
    
    # Count 1 to 5
    print("\nrange(1, 6):")
    for i in range(1, 6):
        print(i, end=" ")
    print()
    
    # Count by 2s
    print("\nrange(0, 10, 2):")
    for i in range(0, 10, 2):
        print(i, end=" ")
    print()
    
    # Countdown
    print("\nrange(5, 0, -1):")
    for i in range(5, 0, -1):
        print(i, end=" ")
    print("Blast off!")

    3. The while Loop

    The while loop repeats as long as a condition is True. Use it when you don't know exactly how many times to repeat.

    # Syntax:

    while condition:

    code to repeat

    update something (important!)

    Try It: Basic while Loop

    Repeat while a condition is True

    Try it Yourself »
    Python
    # Basic while loop
    count = 1
    
    while count <= 5:
        print(f"Count is: {count}")
        count += 1  # This is crucial! Without it, infinite loop!
    
    print("Loop finished!")
    
    # How it works:
    # 1. Check: Is count <= 5? (1 <= 5 = True) → Run code
    # 2. Check: Is count <= 5? (2 <= 5 = True) → Run code
    # ...continues until...
    # 6. Check: Is count <= 5? (6 <= 5 = False) → Exit loop

    ♾️ Infinite Loops and Writing Safe while Loops

    An infinite loop runs forever because its condition never becomes False. Your program freezes and you have to force-quit it. Here's how they happen and how to prevent them.

    ❌ Infinite loop — condition never changes:

    count = 1
    
    while count <= 5:
        print(count)
        # ← Forgot count += 1 !
        # count is always 1
        # 1 <= 5 is always True
        # → Runs forever

    ✅ Safe while loop — guaranteed to exit:

    count = 1
    
    while count <= 5:
        print(count)
        count += 1   # ← Update the variable!
        # count grows each iteration
        # Eventually 6 <= 5 → False
        # → Loop exits cleanly

    The sentinel value pattern — loop until a special value

    A sentinel is a special value that signals "stop". This pattern is everywhere in real programs:

    # Keep asking until user types "quit"
    responses = ["hello", "how are you", "quit"]  # Simulates user input
    index = 0
    
    while True:                         # Intentional infinite loop...
        user_input = responses[index]
        index += 1
    
        if user_input == "quit":        # ...with a guaranteed exit
            print("Goodbye!")
            break
    
        print(f"You said: {user_input}")

    while True: is valid — an intentional infinite loop is fine as long as you have a break condition inside. This pattern is used for menus, game loops, and server request handling.

    Safety net: maximum iteration counter

    MAX_TRIES = 1000
    tries = 0
    
    while some_condition and tries < MAX_TRIES:
        # ... do work ...
        tries += 1
    
    if tries >= MAX_TRIES:
        print("Warning: hit maximum iterations — check your logic!")

    When writing complex while loops, adding a maximum counter is a professional safety habit — it turns an accidental infinite loop into a detectable bug.

    4. When to Use for vs while

    Use forUse while
    You know how many times to repeatYou don't know when to stop
    Looping through a list/stringWaiting for user input
    "Do this 10 times""Keep going until X happens"
    for i in range(10):while not done:

    Quick Rule:

    If you can answer "how many times?" → use for
    If you can answer "until what?" → use while

    🧰 Loop Patterns: The Essential Toolkit

    Five patterns appear in virtually every program that uses loops. Learn to recognise them and you'll be able to solve most loop problems from memory.

    Pattern 1: Accumulator — build a running total

    scores = [85, 92, 78, 96, 73]
    
    total = 0               # ← Start at zero
    for score in scores:
        total += score      # ← Add each item
    
    average = total / len(scores)
    print(f"Total: {total}, Average: {average:.1f}")  # Total: 424, Average: 84.8

    Pattern 2: Counter — count items that match a condition

    words = ["python", "java", "python", "rust", "python", "go"]
    
    python_count = 0        # ← Start at zero
    for word in words:
        if word == "python":
            python_count += 1
    
    print(f"'python' appears {python_count} times")  # 3 times

    Pattern 3: Filter — collect items that meet a condition

    numbers = [3, -1, 7, -4, 0, 9, -2, 5]
    
    positives = []           # ← Start with empty result
    for num in numbers:
        if num > 0:
            positives.append(num)   # ← Add matching items
    
    print(f"Positives: {positives}")  # [3, 7, 9, 5]

    Pattern 4: Maximum/Minimum finder

    temperatures = [18.5, 22.1, 15.3, 25.8, 19.0, 12.4]
    
    highest = temperatures[0]    # ← Assume first is the answer
    for temp in temperatures:
        if temp > highest:
            highest = temp        # ← Update if we find better
    
    print(f"Hottest day: {highest}°C")  # 25.8°C
    
    # Python's built-in does the same:
    print(f"Using max(): {max(temperatures)}°C")

    Pattern 5: Transform — build a new list from an old one

    names = ["alice", "bob", "charlie"]
    
    capitalised = []
    for name in names:
        capitalised.append(name.capitalize())
    
    print(capitalised)  # ['Alice', 'Bob', 'Charlie']

    You'll soon learn a shorter way to write this using list comprehensions — but the pattern is the same.

    5. Loop Control: break and continue

    Sometimes you need more control over your loops. Python provides two special keywords:

    break

    Exit the loop immediately

    Like hitting the emergency stop button

    continue

    Skip to the next iteration

    Like saying "skip this one, move on"

    Try It: break and continue

    Control loop flow with break and continue

    Try it Yourself »
    Python
    # break - exit the loop early
    print("Using break:")
    for i in range(10):
        if i == 5:
            print("Found 5! Stopping.")
            break
        print(i)
    
    print("\n" + "="*30 + "\n")
    
    # continue - skip current iteration
    print("Using continue (skip even numbers):")
    for i in range(10):
        if i % 2 == 0:  # If even
            continue    # Skip to next iteration
        print(i)  # Only prints odd numbers

    🔀 The else Clause on Loops — Python's Hidden Feature

    Python has a feature almost no other language has: an else block on loops. It sounds confusing at first, but it solves a real problem elegantly.

    The rule:

    The else block runs only if the loop completed without hitting a break. If break was triggered, else is skipped entirely.

    Without for/else (old way):

    names = ["Alice", "Bob", "Charlie"]
    search = "Diana"
    found = False       # Need a flag variable
    
    for name in names:
        if name == search:
            print("Found!")
            found = True
            break
    
    if not found:       # Check the flag
        print("Not found")

    With for/else (Pythonic way):

    names = ["Alice", "Bob", "Charlie"]
    search = "Diana"
    
    for name in names:
        if name == search:
            print("Found!")
            break
    else:               # Runs if no break hit
        print("Not found")
    
    # No flag variable needed!

    Real use case: searching for a prime number factor

    def is_prime(n):
        if n < 2:
            return False
        for i in range(2, int(n ** 0.5) + 1):
            if n % i == 0:
                print(f"{n} is divisible by {i} — not prime")
                break
        else:
            print(f"{n} is prime!")   # Only runs if no factor was found
            return True
        return False
    
    is_prime(17)   # 17 is prime!
    is_prime(15)   # 15 is divisible by 3 — not prime

    6. Looping Through Different Data Types

    You can loop through many types of sequences in Python:

    Data TypeWhat You Get Each Iteration
    ListEach item in the list
    StringEach character
    DictionaryEach key (or use .items() for key-value pairs)
    range()Each number in the sequence

    Try It: Looping Through Data Types

    Loop through strings, dictionaries, and more

    Try it Yourself »
    Python
    # Loop through a string
    print("Characters in 'Hello':")
    for char in "Hello":
        print(char, end=" ")
    print()
    
    # Loop through a dictionary
    print("\nPerson info:")
    person = {"name": "Alice", "age": 25, "city": "Paris"}
    for key, value in person.items():
        print(f"  {key}: {value}")
    
    # Use enumerate() to get index + value
    print("\nWith index:")
    colors = ["red", "green", "blue"]
    for i, color in enumerate(colors):
        print(f"  {i}: {color}")

    🔧 Loop Helpers: enumerate(), zip(), and reversed()

    Python includes several built-in functions that make loops dramatically more powerful and readable. These are used constantly in real code.

    enumerate() — get the index alongside the value

    Without it, you'd need a manual counter variable. With it, Python tracks the index for you:

    Old way (manual counter):

    players = ["Alice", "Bob", "Charlie"]
    i = 0
    for player in players:
        print(f"{i+1}. {player}")
        i += 1

    With enumerate():

    players = ["Alice", "Bob", "Charlie"]
    for i, player in enumerate(players, start=1):
        print(f"{i}. {player}")
    # 1. Alice
    # 2. Bob
    # 3. Charlie

    The start=1 argument makes numbering start at 1 instead of 0 — perfect for user-facing lists.

    zip() — loop through two sequences in parallel

    zip() pairs up items from two (or more) sequences, giving you one item from each per iteration:

    names  = ["Alice", "Bob",   "Charlie"]
    scores = [92,      78,      85]
    
    for name, score in zip(names, scores):
        grade = "Pass" if score >= 60 else "Fail"
        print(f"{name}: {score}/100 — {grade}")
    
    # Output:
    # Alice: 92/100 — Pass
    # Bob: 78/100 — Pass
    # Charlie: 85/100 — Pass

    zip() stops at the shortest sequence. If one list has 3 items and another has 5, you get 3 pairs.

    reversed() — loop backwards through a sequence

    steps = ["Open app", "Log in", "Browse", "Checkout", "Pay"]
    
    print("Reverse order:")
    for step in reversed(steps):
        print(f"  ← {step}")
    
    # Countdown using reversed() with range:
    for i in reversed(range(1, 6)):
        print(i, end=" ")
    print("Go!")  # 5 4 3 2 1 Go!

    Remember: these are all "iterables"

    Lists, strings, range(), enumerate(), zip(), and reversed() are all things Python can loop over. The technical term is iterable. Any time you use for x in ___, the blank must be an iterable.

    7. Nested Loops (Loop Inside a Loop)

    You can put a loop inside another loop. The inner loop runs completely for each iteration of the outer loop.

    How nested loops work:

    Outer loop runs once → Inner loop runs completely
    Outer loop runs again → Inner loop runs completely again
    ...and so on

    Try It: Nested Loops

    Create a multiplication table with nested loops

    Try it Yourself »
    Python
    # Nested loop example - multiplication table
    print("3x3 Multiplication Table:")
    print("-" * 15)
    
    for i in range(1, 4):       # Outer: rows 1, 2, 3
        for j in range(1, 4):   # Inner: columns 1, 2, 3
            result = i * j
            print(f"{i}x{j}={result}", end="  ")
        print()  # New line after each row
    
    # How many times does the inner code run?
    # 3 (outer) × 3 (inner) = 9 times

    List Comprehensions: The Pythonic Way to Build Lists

    A list comprehension is a compact, one-line way to build a list using a loop — and it's one of the most distinctly "Pythonic" features of the language. Once you understand them, you'll use them constantly.

    The transformation: for loop → list comprehension

    Traditional for loop (4 lines):

    numbers = [1, 2, 3, 4, 5]
    squared = []
    for n in numbers:
        squared.append(n ** 2)
    # squared = [1, 4, 9, 16, 25]

    List comprehension (1 line — same result):

    numbers = [1, 2, 3, 4, 5]
    squared = [n ** 2 for n in numbers]
    # squared = [1, 4, 9, 16, 25]
    [expression for item in iterable]

    With a filter condition

    numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
    # Only keep even numbers:
    evens = [n for n in numbers if n % 2 == 0]
    print(evens)   # [2, 4, 6, 8, 10]
    
    # Square only the odd numbers:
    odd_squares = [n ** 2 for n in numbers if n % 2 != 0]
    print(odd_squares)   # [1, 9, 25, 49, 81]
    
    # Capitalise names that are longer than 4 letters:
    names = ["Ali", "Bobby", "Charlie", "Di"]
    long_names = [name.upper() for name in names if len(name) > 4]
    print(long_names)   # ['BOBBY', 'CHARLIE']
    [expression for item in iterable if condition]

    Common Mistakes to Avoid

    Forgetting to update the condition in while loops

    This causes infinite loops! Always change something inside the loop.

    Off-by-one errors with range()

    range(5) gives 0-4, not 1-5. Use range(1, 6) for 1-5.

    Modifying a list while looping through it

    This can cause unexpected behavior. Loop through a copy instead.

    Using = instead of == in conditions

    while x = 5: is wrong. Use while x == 5:

    8. Practical Examples

    Example 1: Sum of Numbers

    Sum of Numbers

    Add up numbers from 1 to 100

    Try it Yourself »
    Python
    # Calculate sum of 1 to 100
    total = 0
    
    for num in range(1, 101):
        total += num
    
    print(f"Sum of 1 to 100 = {total}")
    
    # Using Python's built-in (faster):
    print(f"Using sum(): {sum(range(1, 101))}")

    Example 2: Find an Item

    Search Example

    Find an item in a list

    Try it Yourself »
    Python
    # Search for an item in a list
    names = ["Alice", "Bob", "Charlie", "Diana"]
    search_for = "Charlie"
    found = False
    
    for name in names:
        if name == search_for:
            print(f"Found {search_for}!")
            found = True
            break
    
    if not found:
        print(f"{search_for} not in list.")

    Example 3: Password Attempts

    Password Attempts

    Limit login attempts with while loop

    Try it Yourself »
    Python
    # Simulate login attempts
    correct_password = "secret123"
    max_attempts = 3
    attempts = 0
    
    # Simulating different password guesses
    guesses = ["wrong", "also_wrong", "secret123"]
    
    while attempts < max_attempts:
        guess = guesses[attempts]  # Simulate user input
        attempts += 1
        
        if guess == correct_password:
            print(f"Login successful on attempt {attempts}!")
            break
        else:
            remaining = max_attempts - attempts
            print(f"Wrong password. {remaining} attempts left
    ...

    Mini-Project: FizzBuzz and Number Analysis

    FizzBuzz is the most famous beginner programming challenge — it's used in real job interviews to test basic loop and condition logic. If you can write FizzBuzz, you understand loops.

    The rules:

    • • Count from 1 to 100
    • • If a number is divisible by 3 → print "Fizz"
    • • If a number is divisible by 5 → print "Buzz"
    • • If divisible by both 3 and 5 → print "FizzBuzz"
    • • Otherwise → print the number itself

    Classic FizzBuzz — uses: for loop, range(), modulo, if/elif/else

    for i in range(1, 101):
        if i % 3 == 0 and i % 5 == 0:
            print("FizzBuzz")
        elif i % 3 == 0:
            print("Fizz")
        elif i % 5 == 0:
            print("Buzz")
        else:
            print(i)

    Extended version — adds: accumulator, counter, filter patterns

    # FizzBuzz with statistics
    fizz_count   = 0
    buzz_count   = 0
    fizzbuzz_count = 0
    number_sum   = 0    # Sum of numbers that printed as numbers
    
    for i in range(1, 101):
        if i % 15 == 0:
            print("FizzBuzz", end="  ")
            fizzbuzz_count += 1
        elif i % 3 == 0:
            print("Fizz", end="  ")
            fizz_count += 1
        elif i % 5 == 0:
            print("Buzz", end="  ")
            buzz_count += 1
        else:
            print(i, end="  ")
            number_sum += i
    
    print("
    
    === Statistics ===")
    print(f"Fizz:     {fizz_count} times")
    print(f"Buzz:     {buzz_count} times")
    print(f"FizzBuzz: {fizzbuzz_count} times")
    print(f"Numbers:  {100 - fizz_count - buzz_count - fizzbuzz_count}")
    print(f"Sum of plain numbers: {number_sum}")

    Concepts used in this project:

    • for loop + range()
    • Modulo operator (%)
    • if/elif/else chain
    • Accumulator pattern
    • Counter pattern
    • Condition order matters

    Challenge: Can you rewrite the FizzBuzz output using a list comprehension? Hint: you'll need the ternary operator from Lesson 4.

    Summary: Quick Reference

    ConceptWhat It DoesExample
    forLoop through a sequencefor x in list:
    whileLoop while condition is Truewhile x < 10:
    range()Generate number sequencerange(1, 10, 2)
    breakExit loop immediatelyif done: break
    continueSkip to next iterationif skip: continue
    enumerate()Get index + valuefor i, x in enumerate(list):

    Beginner Track Complete!

    Congratulations! You've completed the Python basics. You now know:

    • Variables and data types
    • Operators and expressions
    • Control flow with if/elif/else
    • Loops with for and while

    Next up: Functions - learn how to organize your code into reusable blocks!

    🎉

    🏆 Beginner Track Complete! You've mastered the fundamentals!

    Variables, operators, conditions, and loops — these 5 lessons are the foundation of all programming. Every Python developer in the world uses these exact same tools every single day.

    🚀 Up next: Functions — learn to package your code into reusable blocks so you never repeat yourself.

    Sign up for free to track which lessons you've completed and get learning reminders.

    Previous

    Cookie & Privacy Settings

    We use cookies to improve your experience, analyze traffic, and show personalized ads. You can manage your preferences below.

    By clicking "Accept All", you consent to our use of cookies for analytics and personalized advertising. You can customize your preferences or reject non-essential cookies.

    Privacy PolicyTerms of Service