Loops are core to Python programming—but if written carelessly, they can slow your code down and waste memory.
Let’s explore how to go from naive loops → list comprehensions → generators for faster, cleaner, and memory-efficient Python code.
Naive Loop Example
A simple loop works fine for small datasets but doesn’t scale well:
def square_even(nums): result = [] for n in nums: if n % 2 == 0: result.append(n * n) return result ✅ Easy to read
❌ Builds a full list in memory (bad for millions of items)
Using List Comprehensions
Python’s list comprehensions are faster and more concise:
def square_even_lc(nums): return [n * n for n in nums if n % 2 == 0] ✅ Runs faster
❌ Still consumes memory proportional to list size
Enter Generators (Lazy Evaluation)
Generators produce items on demand, making them ideal for large or streaming data.
def square_even_gen(nums): for n in nums: if n % 2 == 0: yield n * n Use it like this:
for val in square_even_gen(range(10_000_000)): print(val) ✅ Minimal memory usage
✅ Ideal for reading files or streaming data
❌ One-time use (exhausted after iteration)
Quick Performance Comparison
import time nums = range(10_000_00) start = time.time() square_even(nums) print("Naive:", round(time.time() - start, 3), "s") start = time.time() square_even_lc(nums) print("List comprehension:", round(time.time() - start, 3), "s") start = time.time() sum(square_even_gen(nums)) print("Generator:", round(time.time() - start, 3), "s") Typical Result:
- List comprehension: fastest for small/medium data
- Generator: best for huge datasets or limited memory
Conclusion
Optimizing loops isn’t just about speed—it’s about writing scalable and memory-smart Python.
Use list comprehensions for everyday code, and generators when dealing with big data or streaming tasks.
🔗 References
Real Python – Generators in Python
If you enjoyed this blog, follow me for more Python tips and tricks! 🐍
Top comments (0)