Python - List Comprehension with Examples
List comprehension follows the pattern `[expression for item in iterable]`. This syntax replaces the traditional loop-append pattern with a single line.
Key Insights
- List comprehensions provide a concise syntax for creating lists, reducing typical for-loops from 3-4 lines to a single expression while maintaining readability
- Conditional logic in comprehensions enables filtering and transformation in one operation, with if-else supporting both filter and map patterns
- Nested comprehensions handle multi-dimensional data structures efficiently but should be limited to 2-3 levels to preserve code clarity
Basic List Comprehension Syntax
List comprehension follows the pattern [expression for item in iterable]. This syntax replaces the traditional loop-append pattern with a single line.
# Traditional approach
squares = []
for x in range(10):
squares.append(x ** 2)
# List comprehension
squares = [x ** 2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
The comprehension executes faster because Python optimizes it at the bytecode level. The expression x ** 2 evaluates for each element, and the results populate the list directly without explicit append calls.
# String manipulation
words = ['hello', 'world', 'python']
uppercase = [word.upper() for word in words]
# ['HELLO', 'WORLD', 'PYTHON']
# Method chaining
names = [' alice ', ' bob ', ' charlie ']
cleaned = [name.strip().title() for name in names]
# ['Alice', 'Bob', 'Charlie']
Filtering with Conditional Logic
Adding an if clause filters elements before applying the expression. The syntax becomes [expression for item in iterable if condition].
# Filter even numbers
numbers = range(20)
evens = [n for n in numbers if n % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# Filter and transform
prices = [10.50, 25.00, 5.75, 100.00, 15.25]
expensive = [p * 1.1 for p in prices if p > 20]
# [27.5, 110.0]
Multiple conditions combine using and or or operators:
# Multiple filter conditions
data = range(1, 51)
result = [x for x in data if x % 3 == 0 and x % 5 == 0]
# [15, 30, 45]
# Complex filtering
users = [
{'name': 'Alice', 'age': 25, 'active': True},
{'name': 'Bob', 'age': 17, 'active': True},
{'name': 'Charlie', 'age': 30, 'active': False},
{'name': 'David', 'age': 22, 'active': True}
]
active_adults = [u['name'] for u in users if u['age'] >= 18 and u['active']]
# ['Alice', 'David']
If-Else Expressions in Comprehensions
When you need conditional transformation rather than filtering, place the if-else before the for clause: [true_expr if condition else false_expr for item in iterable].
# Categorize numbers
numbers = [-5, 3, -2, 8, -1, 0, 4]
signs = ['positive' if n > 0 else 'negative' if n < 0 else 'zero' for n in numbers]
# ['negative', 'positive', 'negative', 'positive', 'negative', 'zero', 'positive']
# Apply different transformations
values = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
transformed = [x ** 2 if x % 2 == 0 else x ** 3 for x in values]
# [1, 4, 27, 16, 125, 36, 343, 64, 729, 100]
Combining both patterns—transformation with if-else and filtering with trailing if:
# Transform evens, filter out odds
numbers = range(1, 11)
result = [x * 2 if x % 2 == 0 else x for x in numbers if x > 3]
# [5, 8, 7, 16, 9, 20]
Nested List Comprehensions
Nested comprehensions process multi-dimensional structures. The outer loop executes first, followed by inner loops.
# Flatten a 2D matrix
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Create a multiplication table
table = [[i * j for j in range(1, 6)] for i in range(1, 6)]
# [[1, 2, 3, 4, 5],
# [2, 4, 6, 8, 10],
# [3, 6, 9, 12, 15],
# [4, 8, 12, 16, 20],
# [5, 10, 15, 20, 25]]
Nested comprehensions with filtering:
# Extract specific elements from matrix
matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
evens_above_five = [num for row in matrix for num in row if num > 5 and num % 2 == 0]
# [6, 8, 10, 12]
# Cartesian product with condition
colors = ['red', 'blue', 'green']
sizes = ['S', 'M', 'L']
combinations = [(c, s) for c in colors for s in sizes if not (c == 'red' and s == 'L')]
# [('red', 'S'), ('red', 'M'), ('blue', 'S'), ('blue', 'M'), ('blue', 'L'),
# ('green', 'S'), ('green', 'M'), ('green', 'L')]
Working with Dictionaries and Sets
List comprehensions extend to dictionary and set comprehensions with minimal syntax changes.
# Dictionary comprehension
words = ['apple', 'banana', 'cherry']
word_lengths = {word: len(word) for word in words}
# {'apple': 5, 'banana': 6, 'cherry': 6}
# Invert dictionary
original = {'a': 1, 'b': 2, 'c': 3}
inverted = {v: k for k, v in original.items()}
# {1: 'a', 2: 'b', 3: 'c'}
# Set comprehension (automatic deduplication)
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_squares = {x ** 2 for x in numbers}
# {1, 4, 9, 16}
Practical dictionary filtering and transformation:
# Filter and transform dictionary
products = {
'laptop': 1200,
'mouse': 25,
'keyboard': 80,
'monitor': 300,
'cable': 10
}
expensive = {k: v * 0.9 for k, v in products.items() if v > 50}
# {'laptop': 1080.0, 'keyboard': 72.0, 'monitor': 270.0}
Performance Considerations
List comprehensions generally outperform equivalent for-loops due to optimization at the interpreter level.
import timeit
# Performance comparison
def traditional_loop():
result = []
for i in range(1000):
result.append(i ** 2)
return result
def comprehension():
return [i ** 2 for i in range(1000)]
# timeit shows comprehension is typically 15-20% faster
However, generator expressions offer better memory efficiency for large datasets:
# List comprehension - creates entire list in memory
squares_list = [x ** 2 for x in range(1000000)] # ~8MB memory
# Generator expression - lazy evaluation
squares_gen = (x ** 2 for x in range(1000000)) # minimal memory
# Use generator when you only need to iterate once
total = sum(x ** 2 for x in range(1000000))
Real-World Applications
Processing API responses:
# Extract specific fields from API data
api_response = [
{'id': 1, 'name': 'Item A', 'price': 10.50, 'stock': 100},
{'id': 2, 'name': 'Item B', 'price': 25.00, 'stock': 0},
{'id': 3, 'name': 'Item C', 'price': 15.75, 'stock': 50}
]
available_items = [
{'name': item['name'], 'price': item['price']}
for item in api_response
if item['stock'] > 0
]
# [{'name': 'Item A', 'price': 10.5}, {'name': 'Item C', 'price': 15.75}]
File processing:
# Parse CSV-like data
lines = ['name,age,city', 'Alice,25,NYC', 'Bob,30,LA', 'Charlie,35,Chicago']
data = [dict(zip(lines[0].split(','), line.split(','))) for line in lines[1:]]
# [{'name': 'Alice', 'age': '25', 'city': 'NYC'}, ...]
Data validation and cleaning:
# Clean and validate email list
emails = ['user@example.com', 'invalid-email', 'admin@test.com', '', 'test@domain']
valid_emails = [
email.lower().strip()
for email in emails
if email and '@' in email and '.' in email.split('@')[1]
]
# ['user@example.com', 'admin@test.com']
List comprehensions balance conciseness with readability. Use them for straightforward transformations and filtering. When logic becomes complex or nesting exceeds two levels, traditional loops with explicit logic provide better maintainability.