Python Loops — Junior Level¶
Table of Contents¶
- Introduction
- Prerequisites
- Glossary
- Core Concepts
- Real-World Analogies
- Mental Models
- Pros & Cons
- Use Cases
- Code Examples
- Clean Code
- Product Use / Feature
- Error Handling
- Security Considerations
- Performance Tips
- Metrics & Analytics
- Best Practices
- Edge Cases & Pitfalls
- Common Mistakes
- Common Misconceptions
- Tricky Points
- Test
- Tricky Questions
- Cheat Sheet
- Self-Assessment Checklist
- Summary
- What You Can Build
- Further Reading
- Related Topics
- Diagrams & Visual Aids
Introduction¶
Focus: "What is it?" and "How to use it?"
Loops let you repeat a block of code multiple times without writing it over and over. Every program that processes lists, reads files, or waits for user input relies on loops. Python provides two main loop types: for (iterate over a sequence) and while (repeat while a condition is true).
Prerequisites¶
What you should know before studying this topic:
- Required: Basic Python syntax — how to write and run a
.pyfile - Required: Variables and data types — understanding strings, integers, lists
- Required: Conditionals (
if/elif/else) — loops often contain conditions - Helpful but not required: Functions — helps organize loop-heavy code
Glossary¶
| Term | Definition |
|---|---|
| Iteration | One pass through the body of a loop |
| Iterable | Any object you can loop over (list, string, range, dict, set, file) |
| Iterator | An object that produces the next value on demand (__next__()) |
for loop | A loop that iterates over each element in a sequence |
while loop | A loop that repeats as long as a condition is True |
break | Immediately exits the loop |
continue | Skips the rest of the current iteration and jumps to the next one |
range() | Built-in that generates a sequence of integers |
enumerate() | Wraps an iterable and yields (index, value) pairs |
zip() | Combines two or more iterables element by element |
Core Concepts¶
Concept 1: The for Loop¶
The for loop iterates over each element in an iterable. Python does not use C-style for(i=0; i<n; i++); instead, it iterates directly over items.
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# Output: apple, banana, cherry (one per line)
Concept 2: The while Loop¶
The while loop keeps running as long as its condition evaluates to True. You must ensure the condition eventually becomes False, or you get an infinite loop.
Concept 3: range()¶
range() generates a sequence of integers. It takes up to three arguments: range(start, stop, step). The stop value is exclusive.
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 8): # 2, 3, 4, 5, 6, 7
print(i)
for i in range(0, 10, 2): # 0, 2, 4, 6, 8
print(i)
Concept 4: enumerate()¶
When you need both the index and the value while looping, use enumerate() instead of manual index tracking.
colors = ["red", "green", "blue"]
for index, color in enumerate(colors):
print(f"{index}: {color}")
# 0: red
# 1: green
# 2: blue
Concept 5: zip()¶
zip() pairs elements from multiple iterables together. It stops at the shortest iterable.
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
for name, score in zip(names, scores):
print(f"{name}: {score}")
# Alice: 85
# Bob: 92
# Charlie: 78
Concept 6: break and continue¶
breakexits the loop entirely.continueskips the current iteration and moves to the next.
# break — stop at first negative number
numbers = [3, 7, -1, 4, 9]
for n in numbers:
if n < 0:
break
print(n)
# Output: 3, 7
# continue — skip odd numbers
for n in range(6):
if n % 2 != 0:
continue
print(n)
# Output: 0, 2, 4
Concept 7: else Clause on Loops¶
Python loops can have an else block that runs only if the loop completes without hitting break.
for n in [2, 4, 6]:
if n % 2 != 0:
break
else:
print("All numbers are even!")
# Output: All numbers are even!
Concept 8: Nested Loops¶
A loop inside another loop. The inner loop runs completely for each iteration of the outer loop.
for row in range(3):
for col in range(3):
print(f"({row},{col})", end=" ")
print()
# (0,0) (0,1) (0,2)
# (1,0) (1,1) (1,2)
# (2,0) (2,1) (2,2)
Concept 9: Iterating Over Different Data Types¶
# Strings
for char in "Python":
print(char, end=" ") # P y t h o n
# Dictionaries
person = {"name": "Alice", "age": 30}
for key, value in person.items():
print(f"{key}: {value}")
# Sets
unique = {1, 2, 3}
for item in unique:
print(item)
Concept 10: List Comprehensions (Basics)¶
A concise way to create a new list by transforming or filtering elements.
# Traditional loop
squares = []
for x in range(5):
squares.append(x ** 2)
# List comprehension — same result
squares = [x ** 2 for x in range(5)]
# [0, 1, 4, 9, 16]
# With filter
evens = [x for x in range(10) if x % 2 == 0]
# [0, 2, 4, 6, 8]
Real-World Analogies¶
| Concept | Analogy |
|---|---|
for loop | Reading each page of a book one by one — you go through every page from start to finish |
while loop | Stirring soup until it boils — you keep stirring as long as the condition (not boiling) holds |
break | Finding your keys and stopping the search — once found, you stop looking through drawers |
continue | Skipping a song you don't like in a playlist — the playlist keeps playing, you just skip one |
Mental Models¶
The intuition: Think of a for loop as a conveyor belt — items come one at a time, you process each, and they move on. A while loop is like a traffic light — it keeps cycling until the condition changes.
Why this model helps: It makes clear that for is best when you know what you're iterating over, and while is best when you're waiting for a condition to change.
Pros & Cons¶
| Pros | Cons |
|---|---|
| Eliminates code duplication | Infinite loops if condition never becomes False |
| Makes code readable and compact | Deeply nested loops hurt readability |
for loops handle iteration automatically | while loops require manual state management |
| List comprehensions are very Pythonic | List comprehensions can be hard to read if overly complex |
When to use:¶
- Processing every item in a collection
- Repeating an action until a condition is met
- Building new lists/dicts from existing data
When NOT to use:¶
- When a built-in function like
sum(),max(),map()does the job - When recursion is more natural (e.g., tree traversal)
Use Cases¶
- Use Case 1: Reading lines from a file —
for line in open("data.txt") - Use Case 2: Processing API responses — looping through a list of JSON records
- Use Case 3: User input validation —
whileloop until valid input is entered - Use Case 4: Building transformed data — list comprehension to clean a dataset
Code Examples¶
Example 1: Counting Word Frequencies¶
# Count how many times each word appears in a sentence
sentence = "the cat sat on the mat the cat"
words = sentence.split()
word_count = {}
for word in words:
if word in word_count:
word_count[word] += 1
else:
word_count[word] = 1
print(word_count)
# {'the': 3, 'cat': 2, 'sat': 1, 'on': 1, 'mat': 1}
What it does: Splits a sentence into words and counts each word's occurrences. How to run: python word_count.py
Example 2: FizzBuzz¶
# Classic FizzBuzz problem
for i in range(1, 21):
if i % 15 == 0:
print("FizzBuzz")
elif i % 3 == 0:
print("Fizz")
elif i % 5 == 0:
print("Buzz")
else:
print(i)
What it does: Prints numbers 1-20, replacing multiples of 3 with "Fizz", multiples of 5 with "Buzz", and multiples of both with "FizzBuzz".
Example 3: User Input Loop¶
# Keep asking until valid input
while True:
age_str = input("Enter your age: ")
if age_str.isdigit() and int(age_str) > 0:
age = int(age_str)
break
print("Invalid input. Please enter a positive number.")
print(f"Your age is {age}")
What it does: Repeatedly prompts the user for input until a valid positive integer is entered.
Example 4: Multiplication Table with Nested Loops¶
# Print a 5x5 multiplication table
for i in range(1, 6):
for j in range(1, 6):
print(f"{i * j:4}", end="")
print()
# Output:
# 1 2 3 4 5
# 2 4 6 8 10
# 3 6 9 12 15
# 4 8 12 16 20
# 5 10 15 20 25
Example 5: Using enumerate() and zip() Together¶
# Pair students with grades and display with rank
students = ["Alice", "Bob", "Charlie"]
grades = [95, 87, 92]
for rank, (student, grade) in enumerate(zip(students, grades), start=1):
print(f"Rank {rank}: {student} — {grade} points")
# Rank 1: Alice — 95 points
# Rank 2: Bob — 87 points
# Rank 3: Charlie — 92 points
Clean Code¶
Naming (PEP 8 conventions)¶
# ❌ Bad — single-letter or unclear names
for x in y:
d[x] = d.get(x, 0) + 1
# ✅ Clean — descriptive names
for word in words:
word_count[word] = word_count.get(word, 0) + 1
Short Functions¶
# ❌ Too long — loop + process + save in one block
for item in items:
# 20 lines of validation
# 20 lines of transformation
# 10 lines of saving
...
# ✅ Extract into functions
for item in items:
validated = validate(item)
transformed = transform(validated)
save(transformed)
Use Pythonic Idioms¶
# ❌ C-style index loop
for i in range(len(items)):
print(items[i])
# ✅ Pythonic — iterate directly
for item in items:
print(item)
# ❌ Manual counter
i = 0
for item in items:
print(i, item)
i += 1
# ✅ Use enumerate
for i, item in enumerate(items):
print(i, item)
Product Use / Feature¶
1. Django ORM¶
- How it uses Loops: QuerySet iteration —
for user in User.objects.all()lazily fetches rows from the database - Why it matters: Understanding loops helps you process database records efficiently
2. pandas¶
- How it uses Loops:
iterrows(),itertuples(), and vectorized operations replace explicit loops - Why it matters: Knowing when to loop vs. vectorize is crucial for data work
3. Flask/FastAPI¶
- How it uses Loops: Template rendering loops (
{% for %}in Jinja2), processing request data - Why it matters: Every web app loops over data to render pages or process forms
Error Handling¶
Error 1: TypeError — Iterating Over Non-Iterable¶
Why it happens: You can only loop over iterables (lists, strings, ranges, etc.), not plain integers. How to fix:
Error 2: IndexError — Manual Index Out of Range¶
# ❌ Off-by-one error
items = [10, 20, 30]
for i in range(len(items) + 1):
print(items[i]) # IndexError when i == 3
Why it happens: range(len(items) + 1) generates one extra index. How to fix:
Error 3: Modifying a List While Iterating¶
# ❌ Causes skipped elements or RuntimeError with dicts
numbers = [1, 2, 3, 4, 5]
for n in numbers:
if n % 2 == 0:
numbers.remove(n)
print(numbers) # [1, 3, 5]? No — result is [1, 3, 5] sometimes, but unreliable
How to fix:
# ✅ Create a new list
numbers = [1, 2, 3, 4, 5]
numbers = [n for n in numbers if n % 2 != 0]
print(numbers) # [1, 3, 5]
Security Considerations¶
1. Infinite Loop Denial of Service¶
# ❌ User-controlled loop without limit
user_count = int(input("How many times? "))
for i in range(user_count):
expensive_operation()
# ✅ Set a maximum limit
MAX_ITERATIONS = 10_000
user_count = min(int(input("How many times? ")), MAX_ITERATIONS)
for i in range(user_count):
expensive_operation()
Risk: A malicious user could request billions of iterations, exhausting CPU. Mitigation: Always cap loop counts from user input.
2. Never Use eval() in a Loop¶
# ❌ Extremely dangerous — arbitrary code execution
commands = ["print('hi')", "__import__('os').system('rm -rf /')"]
for cmd in commands:
eval(cmd)
# ✅ Use a whitelist of allowed operations
ALLOWED = {"greet": lambda: print("hi")}
for cmd_name in command_names:
if cmd_name in ALLOWED:
ALLOWED[cmd_name]()
Performance Tips¶
Tip 1: Use List Comprehensions Over Manual Loops¶
# ❌ Slower
result = []
for x in range(10000):
result.append(x ** 2)
# ✅ Faster — runs at C speed internally
result = [x ** 2 for x in range(10000)]
Why it's faster: List comprehensions are optimized at the bytecode level and avoid repeated .append() method lookups.
Tip 2: Avoid Repeated Lookups in Loops¶
# ❌ Slower — looks up len() every iteration
for i in range(len(data)):
process(data[i])
# ✅ Faster — iterate directly
for item in data:
process(item)
Tip 3: Use join() Instead of String Concatenation in Loops¶
# ❌ Very slow for large strings — creates new string each time
result = ""
for word in words:
result += word + " "
# ✅ Much faster
result = " ".join(words)
Metrics & Analytics¶
What to Measure¶
| Metric | Why it matters | Tool |
|---|---|---|
| Loop execution time | Identify slow loops | time.perf_counter() |
| Iteration count | Verify expected iterations | Manual counter |
Basic Instrumentation¶
import time
start = time.perf_counter()
for i in range(1_000_000):
_ = i * i
elapsed = time.perf_counter() - start
print(f"Loop completed in {elapsed:.4f}s")
Best Practices¶
- Iterate directly over items instead of using index-based access
- Use
enumerate()when you need both index and value - Use
zip()to iterate over multiple sequences in parallel - Prefer list comprehensions for simple transformations
- Avoid modifying the collection you are iterating over
- Keep loop bodies short — extract complex logic into functions
Edge Cases & Pitfalls¶
Pitfall 1: Modifying a List During Iteration¶
# ❌ Skips elements
items = [1, 2, 3, 4, 5]
for item in items:
if item == 2:
items.remove(item)
print(items) # [1, 3, 4, 5] — 3 was skipped!
What happens: When you remove an element, the list shifts left. The iterator advances and skips the next element. How to fix: Use a list comprehension or iterate over a copy: for item in items[:]:
Pitfall 2: range() Stop Value is Exclusive¶
Pitfall 3: Infinite while Loop¶
# ❌ Forgot to update the condition variable
count = 0
while count < 5:
print(count)
# Missing: count += 1 — this runs forever!
Common Mistakes¶
Mistake 1: Using range(len()) Instead of Direct Iteration¶
# ❌ Unpythonic
for i in range(len(names)):
print(names[i])
# ✅ Pythonic
for name in names:
print(name)
Mistake 2: Creating a List Just to Loop Over It¶
# ❌ Wasteful — creates a list in memory
for item in list(range(1_000_000)):
pass
# ✅ range() is already iterable — no list needed
for item in range(1_000_000):
pass
Mistake 3: Forgetting break in a while True Loop¶
# ❌ Runs forever — no exit condition
while True:
data = input("Enter data: ")
process(data)
# Missing break condition!
Common Misconceptions¶
Misconception 1: "for loops always use numbers"¶
Reality: Python for loops iterate over any iterable — lists, strings, dicts, files, generators, custom objects. They are not counter-based like C's for loop.
Why people think this: Other languages use for(i=0; i<n; i++), which is index-based.
Misconception 2: "break only works in for loops"¶
Reality: break works in both for and while loops. It exits the innermost loop only.
Misconception 3: "List comprehensions are always better than loops"¶
Reality: List comprehensions are great for simple transformations, but complex logic with multiple conditions, side effects, or error handling should stay as regular loops for readability.
Tricky Points¶
Tricky Point 1: else on Loops¶
for n in range(2, 10):
for x in range(2, n):
if n % x == 0:
break
else:
print(f"{n} is prime")
# Output: 2 is prime, 3 is prime, 5 is prime, 7 is prime
Why it's tricky: The else runs when the loop finishes without break. Most beginners expect it to work like if/else. Key takeaway: Think of it as "no-break" — the else runs when no break was triggered.
Tricky Point 2: Loop Variable Scope¶
Why it's tricky: In Python, loop variables are not scoped to the loop. They persist after the loop ends. Key takeaway: The loop variable holds its last value after the loop completes.
Test¶
Multiple Choice¶
1. What does range(2, 8, 2) produce?
- A)
[2, 4, 6, 8] - B)
[2, 4, 6] - C)
[2, 3, 4, 5, 6, 7] - D)
[2, 8, 2]
Answer
B) —range(2, 8, 2) starts at 2, goes up to (but not including) 8, stepping by 2. So it produces 2, 4, 6. 2. What happens when break is executed inside a nested loop?
- A) Both loops stop
- B) Only the innermost loop stops
- C) The program exits
- D) A
SyntaxErroroccurs
Answer
B) —break only exits the innermost loop that contains it. True or False¶
3. The else block of a for loop runs when the loop condition becomes False.
Answer
False — Afor loop doesn't have a "condition" that becomes False. The else block runs when the loop finishes iterating without hitting a break. 4. enumerate() returns a list of tuples.
Answer
False —enumerate() returns an enumerate object (an iterator), not a list. You can convert it to a list with list(enumerate(...)). What's the Output?¶
5. What does this code print?
Answer
Output:2 The loop variable i persists after the loop ends and holds its last value. 6. What does this code print?
Answer
Output:3 The else block does NOT run because break was executed. Only print(i) runs, and i is 3. 7. What is the output?
Answer
Output:[2, 6] The comprehension skips x = 2 due to the filter if x != 2, then doubles 1 and 3. Tricky Questions¶
1. What does list(zip([1, 2, 3], [4, 5])) return?
- A)
[(1, 4), (2, 5), (3, None)] - B)
[(1, 4), (2, 5)] - C)
Error - D)
[(1, 4), (2, 5), (3,)]
Answer
B) —zip() stops at the shortest iterable. The third element of the first list is dropped. Use itertools.zip_longest() to include all elements. 2. How many times does this inner loop body execute?
- A) 3
- B) 4
- C) 7
- D) 12
Answer
D) — The inner loop runs 4 times for each of the 3 outer iterations: 3 x 4 = 12.Cheat Sheet¶
| What | Syntax | Example |
|---|---|---|
| Basic for loop | for x in iterable: | for x in [1,2,3]: print(x) |
| While loop | while condition: | while n < 10: n += 1 |
| Range (start, stop, step) | range(start, stop, step) | range(0, 10, 2) → 0,2,4,6,8 |
| Enumerate | enumerate(iterable, start) | for i, v in enumerate(lst): |
| Zip | zip(iter1, iter2) | for a, b in zip(x, y): |
| Break | break | Exit innermost loop |
| Continue | continue | Skip to next iteration |
| Else on loop | for/while ... else: | Runs if no break |
| List comprehension | [expr for x in iter if cond] | [x*2 for x in range(5)] |
Self-Assessment Checklist¶
I can explain:¶
- The difference between
forandwhileloops - What
break,continue, andelsedo in loops - How
range(),enumerate(), andzip()work - What an iterable vs. an iterator is
I can do:¶
- Write a
forloop over lists, strings, dicts, and sets - Write a
whileloop with proper exit conditions - Use nested loops for 2D data
- Write basic list comprehensions
- Debug infinite loops
Summary¶
forloops iterate over any iterable — prefer them when you know what you're iterating overwhileloops repeat until a condition becomesFalse— use them for unknown iteration countsrange()generates integer sequences;enumerate()gives index+value;zip()pairs iterablesbreakexits a loop;continueskips one iteration;elseruns if nobreakoccurred- List comprehensions are concise one-liner loops for building new lists
- Never modify a list while iterating over it
Next step: Learn about Type Casting and how Python converts between data types.
What You Can Build¶
Projects you can create:¶
- Number guessing game:
whileloop that keeps asking until the user guesses correctly - File line counter:
forloop that reads and counts lines in a text file - Simple grade calculator: Loop through student scores and compute averages
Technologies / tools that use this:¶
- Django / FastAPI — looping over query results, template rendering
- pandas — understanding when to loop vs. use vectorized operations
- Automation scripts — processing files, directories, API responses
Learning path:¶
Further Reading¶
- Official docs: Python
forstatement - Official docs: Python
whilestatement - Official docs:
range() - Book: Fluent Python (Ramalho), Chapter 17 — Iterables, Iterators, and Generators
Related Topics¶
- Conditionals — loops often contain
if/elif/elselogic - Type Casting — converting loop values between types
- List Comprehensions — advanced use of comprehension syntax
- Functions — encapsulating loop logic into reusable functions