Python List Comprehensions and Generator Expressions
List comprehensions and generator expressions are concise, efficient tools for creating and manipulating sequences in Python. In this guide, you’ll learn their syntax, benefits, and practical applications for writing clean and memory-efficient code.
List Comprehensions
List comprehensions provide a compact way to create lists by applying expressions to iterable items.
Syntax
[expression for item in iterable if condition]
Examples
# Squared numbers from 0 to 9
squared_numbers = [x**2 for x in range(10)]
# Even numbers between 0 and 9
even_numbers = [x for x in range(10) if x % 2 == 0]
Benefits
- More concise and readable than traditional loops.
- Often faster due to optimized internal implementation.
Generator Expressions
Generator expressions create iterators that generate values on-the-fly. They use parentheses ()
instead of brackets.
Syntax
(expression for item in iterable if condition)
Example
# Process lines from a large file lazily
large_dataset = (process(line) for line in big_file)
Benefits
- Memory-efficient: Generate items one at a time.
- Ideal for large datasets or streaming data.
Practical Examples
1. Filter Error Logs
error_lines = [line for line in log_file if 'ERROR' in line]
2. Data Transformation
# Extract IDs of active users
user_ids = [user.id for user in users if user.is_active]
3. Lazy Processing with Generators
# Sum squares of numbers without storing the list
total = sum(x**2 for x in range(1000000))
Practice Work
Exercise 1: Convert Loop to Comprehension
Convert this loop into a list comprehension:
numbers = []
for x in range(10):
if x % 3 != 0:
numbers.append(x * 2)
numbers = [x * 2 for x in range(10) if x % 3 != 0]
Exercise 2: Filter with Generator
Use a generator expression to find the first 5 numbers divisible by 7 in a range.
# Hint: itertools.islice can help
import itertools
result = itertools.islice((x for x in range(100) if x % 7 == 0), 5)
Exercise 3: Nested Comprehension
Create a flattened list from a 2D matrix using a comprehension:
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
Workshop: Real-World Applications
Workshop 1: Log Analysis
Parse a log file to count critical errors (assume logs are loaded as a list):
logs = [
"INFO: System started",
"ERROR: Disk full",
"DEBUG: Connection established",
"ERROR: File not found"
]
critical_errors = [log for log in logs if log.startswith("ERROR")]
Workshop 2: Streaming Data
Simulate processing a large CSV file lazily with a generator:
def read_large_file(filename):
with open(filename) as f:
for line in f:
yield line.strip()
data_gen = read_large_file("data.csv")
processed = (line.split(',') for line in data_gen)
Best Practices
- Avoid Over-Nesting: Keep comprehensions simple for readability.
- Prefer Generators for Large Data: Use
()
instead of[]
to save memory. - Use Descriptive Variable Names: e.g.,
user_ids
instead ofids
.
Conclusion
List comprehensions and generator expressions are powerful tools for writing concise, efficient Python code. Use comprehensions for readability and generators for memory efficiency with large datasets.
Next Steps: Explore Python Iterators and Generators or Functional Programming in Python.