Home Python Python for Loop Explained — Syntax, Examples and Common Mistakes

Python for Loop Explained — Syntax, Examples and Common Mistakes

In Plain English 🔥
Imagine you have a bag of 10 apples and you want to check each one for bruises. You don't write a separate rule for apple 1, apple 2, apple 3... you just say 'for every apple in the bag, do this check.' That's exactly what a for loop does in Python — it lets you write one instruction and automatically repeat it for every item in a collection, without you having to count how many items there are.
⚡ Quick Answer
Imagine you have a bag of 10 apples and you want to check each one for bruises. You don't write a separate rule for apple 1, apple 2, apple 3... you just say 'for every apple in the bag, do this check.' That's exactly what a for loop does in Python — it lets you write one instruction and automatically repeat it for every item in a collection, without you having to count how many items there are.

Every real program does repetitive work. A weather app checks temperatures for 365 days. A music app loads every song in your library. An online store applies a discount to every item in your cart. Without a way to repeat actions automatically, you'd have to write the same line of code hundreds of times — which is not just tedious, it's fragile. Change one thing and you'd have to update every single copy.

What a for Loop Actually Does — The Core Idea

A for loop says: 'take this collection of things, visit each one in order, and run the same block of code for each.' Python handles all the counting and moving-forward for you. You just describe what to DO on each visit.

The collection you loop over can be a list of names, a string of characters, a range of numbers — almost anything that holds multiple items. Python calls these 'iterables', but you can think of them as 'anything you can step through one piece at a time.'

The basic shape of a for loop is always the same: the word for, then a variable name you choose (this is your 'current item' holder), then in, then the collection, then a colon. Everything indented below that runs once per item. The indentation is not optional — Python uses it to know which lines belong inside the loop.

first_for_loop.py · PYTHON
123456789
# A simple list of planet names
planets = ["Mercury", "Venus", "Earth", "Mars", "Jupiter"]

# for loop: visit each planet one at a time
for planet in planets:          # 'planet' holds the current item each round
    print(f"Visiting {planet}") # this line runs once per planet

# This line is NOT indented, so it runs AFTER the loop finishes
print("Tour of the solar system complete!")
▶ Output
Visiting Mercury
Visiting Venus
Visiting Earth
Visiting Mars
Visiting Jupiter
Tour of the solar system complete!
🔥
What's That Variable Name?The variable right after `for` (here, `planet`) is created by Python automatically. You name it — pick something that describes one item from the collection. If you're looping over `planets`, call it `planet`. If you're looping over `students`, call it `student`. Clear names make loops read almost like plain English.

Looping Over Numbers with range() — Your Most-Used Tool

Most beginners need to repeat something a set number of times — run a countdown from 10, process 100 items, print a multiplication table. For that, Python gives you range(). It generates a sequence of numbers on demand without storing them all in memory.

range(5) gives you 0, 1, 2, 3, 4 — five numbers starting at zero. This trips up almost every beginner: range counts from zero by default, and the number you pass in is NOT included. Think of it as 'up to but not including 5.'

range(start, stop) lets you control where counting begins. range(1, 6) gives 1, 2, 3, 4, 5. range(start, stop, step) adds a step — range(0, 10, 2) gives you every even number from 0 to 8. You can even count backwards with a negative step: range(5, 0, -1) counts down from 5 to 1.

range_examples.py · PYTHON
1234567891011121314151617181920
# --- Example 1: Basic range, repeat 5 times ---
print("=== Countdown prep ===")
for step_number in range(5):          # generates 0, 1, 2, 3, 4
    print(f"Step {step_number}")

# --- Example 2: range with start and stop ---
print("\n=== Lap counter ===")
for lap in range(1, 6):               # generates 1, 2, 3, 4, 5 (NOT 6)
    print(f"Lap {lap} complete")

# --- Example 3: range with a step (every 2nd number) ---
print("\n=== Even floors only ===")
for floor in range(0, 11, 2):         # 0, 2, 4, 6, 8, 10
    print(f"Elevator stops at floor {floor}")

# --- Example 4: counting backwards ---
print("\n=== Rocket launch ===")
for countdown in range(5, 0, -1):     # 5, 4, 3, 2, 1
    print(f"T-minus {countdown}...")
print("Liftoff!")
▶ Output
=== Countdown prep ===
Step 0
Step 1
Step 2
Step 3
Step 4

=== Lap counter ===
Lap 1 complete
Lap 2 complete
Lap 3 complete
Lap 4 complete
Lap 5 complete

=== Even floors only ===
elevator stops at floor 0
Elevator stops at floor 2
Elevator stops at floor 4
Elevator stops at floor 6
Elevator stops at floor 8
Elevator stops at floor 10

=== Rocket launch ===
T-minus 5...
T-minus 4...
T-minus 3...
T-minus 2...
T-minus 1...
Liftoff!
⚠️
Watch Out: range(5) Starts at 0, Not 1This is the single most common beginner mistake. `range(5)` gives you [0, 1, 2, 3, 4] — five values, but none of them is 5. If you need to print 1 through 5, use `range(1, 6)`. A good mental model: the stop value is a wall the counter hits but never crosses.

Looping Over Strings, Dictionaries, and Using enumerate()

A string in Python is just a sequence of characters, and you can loop over it the same way you loop over a list. Python will hand you one character at a time. This is surprisingly useful for tasks like counting vowels, reversing text, or scanning for special characters.

Dictionaries are a bit different. When you loop over a dictionary directly, you get its keys. To get both keys and values together, use .items() — it hands you both as a pair each round.

Here's a power move: enumerate(). Often you need both the item AND its position number. Without enumerate, beginners create a separate counter variable and increment it manually — messy and error-prone. enumerate(collection) hands you a tuple of (index, item) on each pass. You unpack it by naming two variables after for.

advanced_for_loops.py · PYTHON
123456789101112131415161718192021222324252627
# --- Looping over a string ---
word = "Python"
print("=== Characters in 'Python' ===")
for character in word:               # each character, one at a time
    print(character)

# --- Looping over a dictionary ---
student_grades = {
    "Alice": 92,
    "Bob": 78,
    "Carlos": 85
}
print("\n=== Grade Report ===")
for student_name, grade in student_grades.items():  # .items() gives key AND value
    if grade >= 90:
        remark = "Excellent"
    elif grade >= 80:
        remark = "Good"
    else:
        remark = "Keep practising"
    print(f"{student_name}: {grade} — {remark}")

# --- Using enumerate() to track position ---
race_finishers = ["Aisha", "Ben", "Clara", "David"]
print("\n=== Race Results ===")
for position, runner_name in enumerate(race_finishers, start=1):  # start=1 so positions begin at 1
    print(f"Position {position}: {runner_name}")
▶ Output
=== Characters in 'Python' ===
P
y
t
h
o
n

=== Grade Report ===
Alice: 92 — Excellent
Bob: 78 — Keep practising
Carlos: 85 — Good

=== Race Results ===
Position 1: Aisha
Position 2: Ben
Position 3: Clara
Position 4: David
⚠️
Pro Tip: Always Prefer enumerate() Over a Manual CounterIf you find yourself writing `counter = 0` before a loop and `counter += 1` inside it, stop. That's exactly what `enumerate()` exists to replace. It's cleaner, less likely to have off-by-one bugs, and signals your intent clearly to anyone reading your code.

Controlling the Loop — break, continue, and the else Clause

Sometimes you don't want to visit every single item. Maybe you're searching a list for a specific value and want to stop the moment you find it — no point checking the rest. That's break. It exits the loop immediately, as if you slammed a book shut.

continue is the opposite of a full stop — it's more of a skip. When Python hits continue, it abandons the current iteration and jumps straight to the next one. Useful when you want to process most items but ignore ones that fail a condition.

Python's for loop also has an else clause — and this genuinely surprises most people. The else block runs only if the loop completed normally, meaning it was NOT interrupted by a break. It's perfect for 'search and report' patterns: loop through items looking for something, break if found, and use else to handle the 'not found' case cleanly.

break_continue_else.py · PYTHON
12345678910111213141516171819202122232425262728293031
# --- break: stop the moment we find what we need ---
passenger_list = ["Tom", "Sara", "Jake", "Mia", "Leo"]
target_passenger = "Jake"

print("=== Boarding check ===")
for passenger in passenger_list:
    if passenger == target_passenger:
        print(f"Found {target_passenger}! Stopping search.")
        break                          # no point checking further
    print(f"Not {target_passenger}, checked {passenger}")

# --- continue: skip items that don't qualify ---
raw_scores = [88, -5, 76, 0, 95, -1, 60]
print("\n=== Valid scores only ===")
for score in raw_scores:
    if score <= 0:                     # invalid scores — skip them
        continue
    print(f"Recording score: {score}")

# --- for...else: only runs if loop was NOT broken out of ---
seating_chart = ["14A", "14B", "15A", "15B"]
requested_seat = "16C"

print("\n=== Seat search ===")
for seat in seating_chart:
    if seat == requested_seat:
        print(f"Seat {requested_seat} found!")
        break
else:
    # This block runs ONLY because we never hit 'break'
    print(f"Seat {requested_seat} is not available on this flight.")
▶ Output
=== Boarding check ===
Not Jake, checked Tom
Not Jake, checked Sara
Found Jake! Stopping search.

=== Valid scores only ===
Recording score: 88
Recording score: 76
Recording score: 95
Recording score: 60

=== Seat search ===
Seat 16C is not available on this flight.
🔥
Interview Gold: The for...else ClauseMost Python developers — including experienced ones — forget that `for` loops can have an `else`. Interviewers love asking about this because it shows you've gone beyond the basics. Remember: the `else` runs when the loop finishes without a `break`. Think of it as 'completed without interruption.'
Aspectfor Loopwhile Loop
Best use caseKnown collection or fixed number of iterationsRepeat until a condition changes (unknown count)
Risk of infinite loopVery low — stops when collection is exhaustedHigh — easy to forget updating the condition
Counting built-inYes, via range() or enumerate()No — you manage your own counter
ReadabilityVery readable — intent is obviousCan be harder to scan quickly
Looping over a listNatural — `for item in my_list`Possible but awkward with index management
Typical exampleProcess every order in a cartKeep prompting user until valid input received

🎯 Key Takeaways

  • A for loop visits every item in a collection exactly once — you describe what to do per item, Python handles the counting and advancing automatically.
  • range(stop) starts at 0 and excludes the stop value — range(5) gives 0,1,2,3,4. Use range(1, 6) when you need 1 through 5.
  • Use enumerate() instead of a manual counter variable — it's cleaner, safer, and signals intent clearly to other developers.
  • The for...else clause runs only if the loop was NOT exited via break — it's Python's clean built-in pattern for 'search and handle not-found' logic.

⚠ Common Mistakes to Avoid

  • Mistake 1: Modifying a list while looping over it — The loop skips items silently or throws unexpected results because Python's internal pointer gets confused when the list changes under its feet. Fix: loop over a copy (for item in my_list[:]) or build a new list instead of modifying the original in-place.
  • Mistake 2: Expecting range(n) to include n — Beginners write range(10) expecting to see 10 in the output, but they get 0–9. The symptom is being off by one in calculations or missing the last item. Fix: always remember range's stop value is exclusive. Use range(1, 11) to get 1 through 10.
  • Mistake 3: Using the loop variable after the loop and trusting its value — After a for loop ends, the loop variable still holds the LAST value it was assigned. Beginners sometimes use it assuming it reflects something meaningful. If the loop body never ran (empty list), the variable was never created at all and you'll get a NameError. Fix: if you need a result from a loop, store it explicitly in a variable you control, don't rely on the loop variable post-loop.

Interview Questions on This Topic

  • QWhat is the difference between break and continue in a Python for loop, and can you give a practical example of when you'd use each?
  • QPython's for loop has an else clause — what does it do, and when does the else block actually execute versus when does it get skipped?
  • QIf you need both the index and the value when iterating over a list, what are two ways to do it and which is considered more Pythonic — and why?

Frequently Asked Questions

Can I use a for loop to loop over a string in Python?

Yes, absolutely. A string in Python is a sequence of characters, so for char in 'hello' will visit 'h', 'e', 'l', 'l', 'o' one at a time. This is handy for character-level processing like counting vowels or checking if a string is a palindrome.

What's the difference between for loop and while loop in Python?

Use a for loop when you know in advance what you're iterating over — a list, a range of numbers, a string. Use a while loop when you want to keep repeating until some condition changes and you don't know how many iterations that will take. In practice, for loops cover the majority of everyday repetition tasks.

Why does Python use indentation to define the loop body instead of curly braces?

Python was designed to be readable — indentation makes the structure of the code visually obvious to humans without extra symbols. Everything indented at the same level below the for line is part of the loop body. The moment indentation returns to the previous level, you're outside the loop. This enforces clean, consistent formatting across all Python code.

🔥
TheCodeForge Editorial Team Verified Author

Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.

← Previousif-elif-else in PythonNext →while Loop in Python
Forged with 🔥 at TheCodeForge.io — Where Developers Are Forged