Skip to main content
โšก Calmops

Python Loops: For, While, and Comprehensions Explained

Table of Contents

Introduction

Imagine you need to process 1,000 items in a list. Without loops, you’d write 1,000 lines of nearly identical code. With loops, you write a few lines that repeat automatically. Loops are one of programming’s most powerful toolsโ€”they automate repetitive tasks and make code concise and maintainable.

Python offers multiple ways to iterate: for loops for sequences, while loops for conditions, and comprehensions for elegant transformations. Understanding when and how to use each is essential for writing Pythonic code.

In this guide, we’ll explore all three loop types, from basic iteration to advanced patterns, with practical examples you can apply immediately.


Why Loops Matter

The Problem Without Loops

# Without loops - repetitive and error-prone
numbers = [1, 2, 3, 4, 5]
print(numbers[0])
print(numbers[1])
print(numbers[2])
print(numbers[3])
print(numbers[4])

The Solution With Loops

# With loops - concise and scalable
numbers = [1, 2, 3, 4, 5]
for number in numbers:
    print(number)

Loops eliminate repetition, reduce errors, and make code more maintainable.


For Loops: Iterating Over Sequences

What Are For Loops?

A for loop iterates over a sequence (list, tuple, string, range, etc.) and executes code for each item.

Basic Syntax

for item in sequence:
    # Code here runs for each item
    statement1
    statement2

Iterating Over Lists

# Simple iteration
fruits = ["apple", "banana", "orange"]
for fruit in fruits:
    print(fruit)

# Output:
# apple
# banana
# orange

Iterating Over Ranges

The range() function generates a sequence of numbers:

# range(stop) - from 0 to stop-1
for i in range(5):
    print(i)
# Output: 0, 1, 2, 3, 4

# range(start, stop) - from start to stop-1
for i in range(2, 5):
    print(i)
# Output: 2, 3, 4

# range(start, stop, step) - with custom step
for i in range(0, 10, 2):
    print(i)
# Output: 0, 2, 4, 6, 8

Iterating Over Strings

# Strings are sequences of characters
word = "Python"
for letter in word:
    print(letter)

# Output:
# P
# y
# t
# h
# o
# n

Using enumerate() for Index and Value

When you need both the index and value:

# Without enumerate - manual indexing
fruits = ["apple", "banana", "orange"]
for i in range(len(fruits)):
    print(f"{i}: {fruits[i]}")

# With enumerate - cleaner
for index, fruit in enumerate(fruits):
    print(f"{index}: {fruit}")

# Output:
# 0: apple
# 1: banana
# 2: orange

# Custom starting index
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}: {fruit}")

# Output:
# 1: apple
# 2: banana
# 3: orange

Using zip() to Iterate Over Multiple Sequences

# Combine multiple sequences
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]
cities = ["New York", "London", "Paris"]

for name, age, city in zip(names, ages, cities):
    print(f"{name} is {age} years old and lives in {city}")

# Output:
# Alice is 25 years old and lives in New York
# Bob is 30 years old and lives in London
# Charlie is 35 years old and lives in Paris

Iterating Over Dictionaries

# Iterate over keys
person = {"name": "Alice", "age": 25, "city": "New York"}
for key in person:
    print(key)
# Output: name, age, city

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

# Output:
# name: Alice
# age: 25
# city: New York

# Iterate over values only
for value in person.values():
    print(value)
# Output: Alice, 25, New York

Real-World Example: Processing Data

# Calculate total sales
sales = [100, 250, 150, 300, 200]
total = 0

for sale in sales:
    total += sale

print(f"Total sales: ${total}")
# Output: Total sales: $1000

# Find average
average = total / len(sales)
print(f"Average sale: ${average}")
# Output: Average sale: $250.0

While Loops: Condition-Based Iteration

What Are While Loops?

A while loop repeats code as long as a condition is true. Unlike for loops that iterate over sequences, while loops continue until a condition becomes false.

Basic Syntax

while condition:
    # Code here runs while condition is True
    statement1
    statement2

Simple Example

# Count down from 5
count = 5
while count > 0:
    print(count)
    count -= 1

# Output:
# 5
# 4
# 3
# 2
# 1

User Input Loop

# Keep asking until valid input
while True:
    age = input("Enter your age: ")
    if age.isdigit() and int(age) > 0:
        print(f"You are {age} years old")
        break  # Exit the loop
    else:
        print("Please enter a valid age")

Real-World Example: Game Loop

# Simple guessing game
import random

secret_number = random.randint(1, 100)
guess = None
attempts = 0

while guess != secret_number:
    guess = int(input("Guess a number between 1 and 100: "))
    attempts += 1
    
    if guess < secret_number:
        print("Too low!")
    elif guess > secret_number:
        print("Too high!")
    else:
        print(f"Correct! You guessed it in {attempts} attempts")

Avoiding Infinite Loops

An infinite loop never terminates. Always ensure your condition will eventually become false:

# Bad: Infinite loop
count = 0
while count < 10:
    print(count)
    # Forgot to increment count!

# Good: Proper termination
count = 0
while count < 10:
    print(count)
    count += 1  # Increment to eventually exit

Break and Continue

Control loop flow with break and continue:

# break - exit the loop immediately
for i in range(10):
    if i == 5:
        break  # Exit when i equals 5
    print(i)
# Output: 0, 1, 2, 3, 4

# continue - skip to next iteration
for i in range(5):
    if i == 2:
        continue  # Skip when i equals 2
    print(i)
# Output: 0, 1, 3, 4

List Comprehensions: Elegant Iteration

What Are List Comprehensions?

List comprehensions provide a concise way to create lists by applying an expression to each item in a sequence. They’re more readable and faster than equivalent for loops.

Basic Syntax

[expression for item in sequence]

Simple Examples

# Create a list of squares
numbers = [1, 2, 3, 4, 5]
squares = [x**2 for x in numbers]
print(squares)
# Output: [1, 4, 9, 16, 25]

# Convert strings to uppercase
words = ["hello", "world", "python"]
uppercase = [word.upper() for word in words]
print(uppercase)
# Output: ['HELLO', 'WORLD', 'PYTHON']

# Create a range of numbers
numbers = [x for x in range(10)]
print(numbers)
# Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

List Comprehensions with Conditions

Filter items using conditions:

# Get only even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [x for x in numbers if x % 2 == 0]
print(evens)
# Output: [2, 4, 6, 8, 10]

# Get numbers greater than 5
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
large = [x for x in numbers if x > 5]
print(large)
# Output: [6, 7, 8, 9, 10]

# Filter and transform
words = ["hello", "world", "python"]
long_uppercase = [word.upper() for word in words if len(word) > 5]
print(long_uppercase)
# Output: ['PYTHON']

Nested List Comprehensions

# Flatten a 2D list
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [x for row in matrix for x in row]
print(flattened)
# Output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

# Create a multiplication table
table = [x * y for x in range(1, 4) for y in range(1, 4)]
print(table)
# Output: [1, 2, 3, 2, 4, 6, 3, 6, 9]

# Nested with conditions
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
evens = [x for row in matrix for x in row if x % 2 == 0]
print(evens)
# Output: [2, 4, 6, 8]

List Comprehension vs. For Loop

# For loop approach
squares = []
for x in range(10):
    squares.append(x**2)

# List comprehension approach (more concise)
squares = [x**2 for x in range(10)]

# Both produce: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Dictionary Comprehensions

Basic Syntax

{key_expression: value_expression for item in sequence}

Simple Examples

# Create a dictionary of squares
numbers = [1, 2, 3, 4, 5]
squares = {x: x**2 for x in numbers}
print(squares)
# Output: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

# Create a dictionary from lists
keys = ["a", "b", "c"]
values = [1, 2, 3]
mapping = {k: v for k, v in zip(keys, values)}
print(mapping)
# Output: {'a': 1, 'b': 2, 'c': 3}

Dictionary Comprehensions with Conditions

# Filter and create dictionary
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares = {x: x**2 for x in numbers if x % 2 == 0}
print(even_squares)
# Output: {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}

# Transform dictionary
person = {"name": "Alice", "age": 25, "city": "New York"}
uppercase = {k: v.upper() if isinstance(v, str) else v for k, v in person.items()}
print(uppercase)
# Output: {'name': 'ALICE', 'age': 25, 'city': 'NEW YORK'}

Real-World Example: Counting Occurrences

# Count word frequencies
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
word_count = {word: words.count(word) for word in set(words)}
print(word_count)
# Output: {'apple': 3, 'banana': 2, 'cherry': 1}

Set Comprehensions

Basic Syntax

{expression for item in sequence}

Simple Examples

# Create a set of squares
numbers = [1, 2, 3, 4, 5, 5, 5]
squares = {x**2 for x in numbers}
print(squares)
# Output: {1, 4, 9, 16, 25}

# Get unique words
words = ["hello", "world", "hello", "python", "world"]
unique = {word.upper() for word in words}
print(unique)
# Output: {'HELLO', 'WORLD', 'PYTHON'}

Set Comprehensions with Conditions

# Get unique even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 2, 4, 6]
unique_evens = {x for x in numbers if x % 2 == 0}
print(unique_evens)
# Output: {2, 4, 6, 8, 10}

Performance Considerations

Comprehensions vs. Loops

Comprehensions are generally faster than equivalent for loops:

import timeit

# For loop
def for_loop():
    result = []
    for x in range(1000):
        result.append(x**2)
    return result

# List comprehension
def list_comp():
    return [x**2 for x in range(1000)]

# Time both approaches
for_time = timeit.timeit(for_loop, number=10000)
comp_time = timeit.timeit(list_comp, number=10000)

print(f"For loop: {for_time:.4f}s")
print(f"Comprehension: {comp_time:.4f}s")
# Comprehensions are typically 20-30% faster

When to Use Each Loop Type

Loop Type Best For Example
For loop Iterating over sequences Processing list items
While loop Condition-based iteration User input validation
List comprehension Creating new lists Filtering and transforming
Dict comprehension Creating dictionaries Mapping values
Set comprehension Creating sets Finding unique items

Common Pitfalls and Best Practices

Pitfall 1: Modifying a List While Iterating

# Bad: Modifying list during iteration
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)  # Causes issues!

# Good: Create a new list
numbers = [1, 2, 3, 4, 5]
numbers = [num for num in numbers if num % 2 != 0]

Pitfall 2: Infinite Loops

# Bad: Infinite loop
while True:
    print("This runs forever!")
    # No break condition

# Good: Clear exit condition
count = 0
while count < 10:
    print(count)
    count += 1

Pitfall 3: Off-by-One Errors

# Bad: Misunderstanding range
for i in range(5):
    print(i)  # Prints 0-4, not 1-5

# Good: Use correct range
for i in range(1, 6):
    print(i)  # Prints 1-5

Pitfall 4: Overly Complex Comprehensions

# Bad: Too complex to read
result = [x**2 if x % 2 == 0 else x**3 for x in range(10) if x > 2 and x < 8]

# Good: Use a for loop for clarity
result = []
for x in range(10):
    if x > 2 and x < 8:
        if x % 2 == 0:
            result.append(x**2)
        else:
            result.append(x**3)

Best Practice 1: Use Descriptive Variable Names

# Bad: Unclear variable names
for x in data:
    print(x)

# Good: Descriptive names
for customer in customers:
    print(customer)

Best Practice 2: Keep Comprehensions Simple

# Bad: Complex nested comprehension
result = [[y**2 for y in x if y % 2 == 0] for x in matrix if len(x) > 0]

# Good: Use a for loop for clarity
result = []
for row in matrix:
    if len(row) > 0:
        squared_evens = [y**2 for y in row if y % 2 == 0]
        result.append(squared_evens)

Best Practice 3: Use enumerate() When You Need Index

# Bad: Manual indexing
for i in range(len(items)):
    print(f"{i}: {items[i]}")

# Good: Use enumerate
for i, item in enumerate(items):
    print(f"{i}: {item}")

Real-World Applications

Application 1: Data Processing

# Process sales data
sales_data = [
    {"product": "Laptop", "price": 999, "quantity": 2},
    {"product": "Mouse", "price": 29, "quantity": 5},
    {"product": "Keyboard", "price": 79, "quantity": 3}
]

# Calculate total revenue
total_revenue = sum(item["price"] * item["quantity"] for item in sales_data)
print(f"Total revenue: ${total_revenue}")
# Output: Total revenue: $3092

# Get product names
products = [item["product"] for item in sales_data]
print(products)
# Output: ['Laptop', 'Mouse', 'Keyboard']

# Filter expensive items
expensive = [item for item in sales_data if item["price"] > 50]
print(expensive)
# Output: [{'product': 'Laptop', 'price': 999, 'quantity': 2}, {'product': 'Keyboard', 'price': 79, 'quantity': 3}]

Application 2: Text Processing

# Process text data
text = "The quick brown fox jumps over the lazy dog"

# Count word lengths
word_lengths = {word: len(word) for word in text.split()}
print(word_lengths)
# Output: {'The': 3, 'quick': 5, 'brown': 5, 'fox': 3, ...}

# Find long words
long_words = [word for word in text.split() if len(word) > 4]
print(long_words)
# Output: ['quick', 'brown', 'jumps']

# Get unique letters
unique_letters = {letter for letter in text if letter.isalpha()}
print(len(unique_letters))
# Output: 26

Application 3: Data Validation

# Validate user input
def validate_emails(emails):
    """Filter valid email addresses."""
    return [email for email in emails if "@" in email and "." in email]

emails = ["[email protected]", "bob@invalid", "[email protected]", "dave@"]
valid = validate_emails(emails)
print(valid)
# Output: ['[email protected]', '[email protected]']

Conclusion

Loops are essential to Python programming. Each loop type serves a specific purpose:

Key takeaways:

  1. For loops iterate over sequences efficiently
  2. While loops repeat based on conditions
  3. List comprehensions create lists concisely and quickly
  4. Dictionary comprehensions create dictionaries elegantly
  5. Set comprehensions create unique collections
  6. enumerate() provides index and value simultaneously
  7. zip() combines multiple sequences
  8. Comprehensions are faster than equivalent for loops
  9. Keep comprehensions simple for readability
  10. Avoid infinite loops by ensuring exit conditions

Master these loop types, and you’ll write cleaner, faster, more Pythonic code. Start with simple loops, then gradually incorporate comprehensions as you gain confidence.

Happy looping! ๐Ÿ


Quick Reference

# For loop
for item in sequence:
    statement

# For loop with range
for i in range(10):
    statement

# For loop with enumerate
for index, item in enumerate(sequence):
    statement

# For loop with zip
for item1, item2 in zip(list1, list2):
    statement

# While loop
while condition:
    statement

# Break and continue
for item in sequence:
    if condition:
        break  # Exit loop
    if condition:
        continue  # Skip to next iteration

# List comprehension
[expression for item in sequence]
[expression for item in sequence if condition]

# Dictionary comprehension
{key: value for item in sequence}
{key: value for item in sequence if condition}

# Set comprehension
{expression for item in sequence}
{expression for item in sequence if condition}

Comments