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
pythonimport 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 Case | Comprehension | Loop |
|---|---|---|
| Simple transform or filter | ✅ | |
| Multiple outputs (results + errors) | ✅ | |
| Side effects (logging, I/O) | ✅ | |
| Early exit ( text text | ✅ | |
| Nested complex logic (3+ steps) | ✅ | |
| Memory-sensitive (use generator text | ✅ | |
| Readability is #1 priority | Case-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.