🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
NEWSLIVESearch All Content
💼 Servicesℹ️ About✉️ ContactView Pricing Plansfrom $10

Python Loops — for, while, and Iterator Patterns

Python BasicsLoops🟢 Free Lesson

Advertisement

Python Loops — for, while, and Iterator Patterns

Loops let you execute a block of code repeatedly. Python provides two primary loop constructs — for and while — along with powerful iteration utilities. This tutorial covers everything from basic syntax to advanced iterator techniques used in production Python code.

Learning Objectives

  • Understand for and while loop syntax and when to use each
  • Master range(), enumerate(), zip(), and other iteration tools
  • Use break, continue, and the else clause effectively
  • Recognize and avoid common loop mistakes
  • Apply accumulator, filter, and transform patterns
  • Write efficient loops that avoid unnecessary computation

The for Loop

The for loop iterates over any iterable — lists, tuples, strings, dicts, sets, ranges, and more. Python's for is a foreach loop: it visits each element in order.

python
for variable in iterable:
    # do something with variable

Iterating Over Sequences

python
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
    print(fruit)
# apple
# banana
# cherry

coordinates = (10, 20, 30)
for coord in coordinates:
    print(f"Coordinate: {coord}")
# Coordinate: 10
# Coordinate: 20
# Coordinate: 30

The range() Function

range(start, stop, step) generates a sequence of integers. The sequence stops before stop.

python
# 0 to 4
for i in range(5):
    print(i, end=" ")   # 0 1 2 3 4

# Custom start and stop
for i in range(2, 7):
    print(i, end=" ")   # 2 3 4 5 6

# With step
for i in range(0, 20, 3):
    print(i, end=" ")   # 0 3 6 9 12 15 18

# Counting backwards
for i in range(10, 0, -2):
    print(i, end=" ")   # 10 8 6 4 2

Iterating Over Dictionaries

python
person = {"name": "Alice", "age": 30, "city": "Portland"}

for key in person:             # keys (default)
    print(key)

for key in person.keys():      # keys explicitly
    print(key)

for value in person.values():  # values
    print(value)

for key, value in person.items():  # key-value pairs
    print(f"{key}: {value}")

Iterating Over Sets and Strings

python
unique_numbers = {1, 2, 3, 4, 5}
for num in unique_numbers:
    print(num, end=" ")    # order not guaranteed

for char in "Python":
    print(char, end=" ")   # P y t h o n

Nested for Loops

python
for i in range(3):
    for j in range(3):
        print(f"({i},{j})", end=" ")
    print()
# (0,0) (0,1) (0,2)
# (1,0) (1,1) (1,2)
# (2,0) (2,1) (2,2)

The while Loop

A while loop continues as long as its condition is True. Use it when you do not know in advance how many iterations you need.

python
while condition:
    # code block — condition must eventually become False

Simple Counter

python
count = 0
while count < 5:
    print(count, end=" ")
    count += 1
# 0 1 2 3 4

Infinite Loops (When They Are Useful)

Infinite loops are intentional in servers, game loops, and event handlers. Always provide an exit mechanism.

python
running = True
frame = 0
while running:
    frame += 1
    if frame >= 3:
        running = False
    print(f"Frame {frame}")
# Frame 1
# Frame 2
# Frame 3

The while True Pattern

python
iteration = 0
max_iterations = 5

while True:
    iteration += 1
    if iteration > max_iterations:
        break
    print(f"Processing item {iteration}")
# Processing item 1 through 5

Sentinel Value Loop

python
values = [10, 25, 37, 42, 58, 63, 71]
index = 0
while index < len(values) and values[index] < 50:
    print(values[index], end=" ")
    index += 1
# 10 25 37 42

break and continue

break — Exit the Loop Early

break immediately terminates the innermost loop.

python
numbers = [3, 7, 2, 9, 4, 6, 8]
for num in numbers:
    if num > 5:
        print(f"First number greater than 5: {num}")
        break
# First number greater than 5: 7

continue — Skip to Next Iteration

continue jumps to the next iteration, skipping the rest of the body.

python
for i in range(10):
    if i % 2 == 0:
        continue
    print(i, end=" ")
# 1 3 5 7 9

Combining break and continue

python
for i in range(20):
    if i % 3 == 0:
        continue
    if i > 14:
        break
    print(i, end=" ")
# 1 2 4 5 7 8 10 11 13 14

The for-else and while-else

Python loops can have an else clause. It runs only if the loop completes without hitting break. Think of it as "no break occurred," not "condition is false."

Search Pattern

python
primes = [2, 3, 5, 7, 11, 13, 17]
target = 19

for prime in primes:
    if prime == target:
        print(f"Found {target}!")
        break
else:
    print(f"{target} is not in the list")
# 19 is not in the list
python
target = 7
for prime in primes:
    if prime == target:
        print(f"Found {target}!")
        break
else:
    print(f"{target} is not in the list")
# Found 7!

Common Misunderstanding

python
# else runs because loop finished normally (no break)
for i in range(3):
    print(i)
else:
    print("Loop completed without break")
# 0
# 1
# 2
# Loop completed without break

enumerate()

enumerate() adds a counter to any iterable, returning (index, value) tuples.

python
colors = ["red", "green", "blue"]

for index, color in enumerate(colors):
    print(f"{index}: {color}")
# 0: red
# 1: green
# 2: blue

Custom Start Index

python
for index, color in enumerate(colors, start=1):
    print(f"{index}: {color}")
# 1: red
# 2: green
# 3: blue

Why Not range(len())?

enumerate() is better because it works with any iterable, avoids off-by-one errors, is more readable, and is slightly faster in CPython. Prefer it over range(len(...)).


zip()

zip() combines multiple iterables into tuples, stopping at the shortest one.

python
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

Creating a Dictionary with zip

python
keys = ["name", "age", "city"]
values = ["Alice", 30, "Portland"]
person = dict(zip(keys, values))
# {'name': 'Alice', 'age': 30, 'city': 'Portland'}

Strict Mode (Python 3.10+)

With strict=True, zip raises ValueError if lengths differ:

python
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92]
try:
    list(zip(names, scores, strict=True))
except ValueError as e:
    print(f"Error: {e}")
# Error: zip() has arguments with different lengths

itertools.zip_longest

Process all elements, filling missing values:

python
from itertools import zip_longest
names = ["Alice", "Bob", "Charlie", "Diana"]
scores = [85, 92]
for name, score in zip_longest(names, scores, fillvalue="N/A"):
    print(f"{name}: {score}")
# Alice: 85
# Bob: 92
# Charlie: N/A
# Diana: N/A

Iterating Techniques

Reversed()

Iterate in reverse without modifying the original:

python
numbers = [1, 2, 3, 4, 5]
for num in reversed(numbers):
    print(num, end=" ")
# 5 4 3 2 1

any() and all() with Generators

python
numbers = [2, 4, 6, 8, 10]
print(all(n % 2 == 0 for n in numbers))  # True
print(any(n > 7 for n in numbers))       # True
print(any(n < 0 for n in numbers))       # False

Loop Patterns

Accumulator Pattern

Collect results as you iterate:

python
numbers = [1, 2, 3, 4, 5]
total = 0
for num in numbers:
    total += num
print(f"Sum: {total}")  # Sum: 15

Filter Pattern

Keep only items that match:

python
scores = [85, 42, 91, 38, 76, 55, 88]
passing = [s for s in scores if s >= 60]
print(passing)  # [85, 91, 76, 88]

Transform Pattern

Convert each element:

python
celsius = [0, 10, 20, 30, 40]
fahrenheit = [t * 9 / 5 + 32 for t in celsius]
print(fahrenheit)  # [32.0, 50.0, 68.0, 86.0, 104.0]

Find First / Any / All

python
data = [3, 7, 11, 2, 9, 4]

first_even = None
for num in data:
    if num % 2 == 0:
        first_even = num
        break
print(f"First even: {first_even}")  # First even: 2

all_positive = all(num > 0 for num in data)
print(f"All positive: {all_positive}")  # All positive: True

Dictionary Building in Loops

python
words = ["apple", "banana", "cherry", "avocado", "blueberry"]
grouped = {}
for word in words:
    letter = word[0]
    if letter not in grouped:
        grouped[letter] = []
    grouped[letter].append(word)
# {'a': ['apple', 'avocado'], 'b': ['banana', 'blueberry'], 'c': ['cherry']}

Nested Loops vs List Comprehensions

python
# Nested loop
pairs = []
for i in range(4):
    for j in range(i + 1, 4):
        pairs.append((i, j))

# Equivalent comprehension
pairs = [(i, j) for i in range(4) for j in range(i + 1, 4)]
# [(0, 1), (0, 2), (0, 3), (1, 2), (1, 3), (2, 3)]

# Flattening nested lists
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [val for row in matrix for val in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]

Performance

for vs while

for loops are faster because they are optimized at the C level. Use for when possible; use while only when the exit condition depends on runtime logic.

python
import time
n = 1_000_000

start = time.time()
for i in range(n):
    pass
for_time = time.time() - start

start = time.time()
i = 0
while i < n:
    i += 1
while_time = time.time() - start

print(f"for:  {for_time:.4f}s")   # ~0.05s
print(f"while: {while_time:.4f}s") # ~0.08s

Generator Expressions for Memory

python
import sys

# List — stores everything in memory
squares_list = [x ** 2 for x in range(1_000_000)]

# Generator — yields one at a time
squares_gen = (x ** 2 for x in range(1_000_000))

print(sys.getsizeof(squares_list))  # ~8 MB
print(sys.getsizeof(squares_gen))   # ~200 bytes

Common Mistakes

Infinite while Loops

python
# Wrong — forgot to update condition
x = 0
# while x < 5:
#     print(x)  # infinite loop!

# Right
x = 0
while x < 5:
    print(x, end=" ")
    x += 1
# 0 1 2 3 4

Modifying a List During Iteration

python
# Wrong — skips elements
numbers = [1, 2, 3, 4, 5]
# for num in numbers:
#     if num % 2 == 0:
#         numbers.remove(num)

# Right — iterate over a copy
numbers = [1, 2, 3, 4, 5]
for num in numbers[:]:
    if num % 2 == 0:
        numbers.remove(num)
print(numbers)  # [1, 3, 5]

range() Off-by-One

python
items = ["a", "b", "c", "d"]
# Use zip to iterate pairs instead of index math
for a, b in zip(items, items[1:]):
    print(a, b)
# a b
# b c
# c d

else Clause Confusion

python
# else runs when loop completes without break
for i in range(5):
    pass
else:
    print("Runs — no break occurred")

for i in range(5):
    if i == 3:
        break
else:
    print("Does NOT print — break occurred")

Not Using enumerate

python
fruits = ["apple", "banana", "cherry"]

# Not Pythonic
i = 0
for fruit in fruits:
    print(f"{i}: {fruit}")
    i += 1

# Pythonic
for i, fruit in enumerate(fruits):
    print(f"{i}: {fruit}")

Practice Exercises

Exercise 1: Factorial Calculator

Write a loop that computes the factorial of a number (n!) using both for and while.

Solution

python
def factorial_for(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

def factorial_while(n):
    result = 1
    i = 1
    while i <= n:
        result *= i
        i += 1
    return result

print(factorial_for(5))   # 120
print(factorial_while(5)) # 120

Exercise 2: FizzBuzz

Print 1 through 30. Multiples of 3 -> "Fizz". Multiples of 5 -> "Buzz". Both -> "FizzBuzz".

Solution

python
for i in range(1, 31):
    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)

Exercise 3: Find Duplicates

Find all duplicate elements in a list using enumerate and a set.

Solution

python
numbers = [1, 3, 5, 3, 7, 1, 9, 5, 3]
seen = set()
duplicates = set()
for num in numbers:
    if num in seen:
        duplicates.add(num)
    seen.add(num)
print(f"Duplicates: {sorted(duplicates)}")
# Duplicates: [1, 3, 5]

Key Takeaways

ConceptSyntaxWhen to Use
for loopfor x in iter:Known or finite iterations
while loopwhile cond:Unknown iteration count
range()range(start, stop, step)Numeric sequences
enumerate()enumerate(iter, start=0)Need index + value
zip()zip(a, b, ...)Parallel iteration
breakbreakExit loop early
continuecontinueSkip current iteration
elseelse: (after loop)Run if no break occurred
  • Use for when iterating over a known sequence; while when the exit condition depends on runtime logic.
  • enumerate() is almost always better than range(len(...)).
  • zip() pairs elements from multiple iterables — use strict=True to catch length mismatches.
  • The else clause on loops runs when the loop finishes without break.
  • Prefer generator expressions for large datasets to save memory.
  • Never modify a collection while iterating over it — iterate over a copy instead.
  • reversed() iterates in reverse without modifying the original sequence.
  • any() and all() with generator expressions provide efficient boolean checks.
—
☆☆☆☆☆
0 ratings

Rate & Feedback

Need Expert Python Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement