Concept #23Mediumpython-for-gen-ai

Explain list comprehensions vs. loops in Python. When is each appropriate?

#gen-ai#python

Answer

List Comprehensions vs Loops

List Comprehensions

A concise, readable way to create lists by transforming or filtering an iterable in a single expression.

python
# Basic syntax
squares = [x**2 for x in range(10)]

# With filter
even_squares = [x**2 for x in range(10) if x % 2 == 0]

# Nested
pairs = [(x, y) for x in range(3) for y in range(3) if x != y]

Comparison in Gen AI Context

python
# ❌ Loop — verbose for simple transformation
token_lengths = []
for doc in documents:
    token_lengths.append(len(doc.split()))

# ✅ Comprehension — cleaner, slightly faster
token_lengths = [len(doc.split()) for doc in documents]

# ❌ Loop for filtering
valid_docs = []
for doc in documents:
    if len(doc.split()) >= 50:
        valid_docs.append(doc)

# ✅ Comprehension
valid_docs = [doc for doc in documents if len(doc.split()) >= 50]

Other Comprehension Types

python
# Dict comprehension
word_counts = {doc.id: len(doc.content.split()) for doc in documents}

# Set comprehension — deduplicate tags
all_tags = {tag for doc in documents for tag in doc.tags}

# Generator expression — memory-efficient (no brackets = no list in memory)
total_tokens = sum(len(doc.split()) for doc in huge_corpus)

When to Use Loops Instead

python
# ✅ Use a loop when:

# 1. Multiple outputs / side effects
results = []
errors = []
for doc in documents:
    try:
        embedding = embed(doc)
        results.append(embedding)
    except Exception as e:
        errors.append((doc, e))  # Can't do this cleanly in comprehension

# 2. Early exit / break
for doc in documents:
    if "stop" in doc:
        break  # No break in comprehensions
    process(doc)

# 3. Complex multi-step transformations (readability matters)
processed = []
for doc in raw_documents:
    cleaned = clean_text(doc)
    chunked = chunk(cleaned, size=512)
    validated = validate_chunks(chunked)
    processed.extend(validated)

Performance

python
import timeit

# Comprehension is typically 30-40% faster than equivalent loop
loop_time = timeit.timeit(
    '[x**2 for x in range(10000)]', number=1000
)
# vs
manual_time = timeit.timeit('''
result = []
for x in range(10000):
    result.append(x**2)
''', number=1000)

Decision Guide

Use CaseComprehensionLoop
Simple transform or filter
Multiple outputs (results + errors)
Side effects (logging, I/O)
Early exit (
text
break
/
text
continue
)
Nested complex logic (3+ steps)
Memory-sensitive (use generator
text
()
)
Readability is #1 priorityCase-by-case

Rule of thumb: If the comprehension fits on one readable line, use it. If you need to read it twice to understand it, use a loop.