advanced
Step 13 of 20
List Comprehensions
Python Programming
List Comprehensions
List comprehensions are one of Python's most beloved features, allowing you to create new lists by transforming and filtering existing iterables in a single, readable expression. They replace the common pattern of initializing an empty list, looping over data, and appending results. Comprehensions are not only more concise but often faster than equivalent for-loop constructions because they are optimized internally by the Python interpreter. Beyond lists, Python also supports dictionary and set comprehensions, as well as generator expressions for memory-efficient processing.
Basic List Comprehensions
# Traditional approach
squares = []
for x in range(10):
squares.append(x ** 2)
# List comprehension — same result, one line
squares = [x ** 2 for x in range(10)]
print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# Syntax: [expression for item in iterable]
# More examples
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
# ['ALICE', 'BOB', 'CHARLIE']
lengths = [len(name) for name in names]
# [5, 3, 7]
# With function calls
import math
roots = [math.sqrt(x) for x in range(1, 6)]
# [1.0, 1.414..., 1.732..., 2.0, 2.236...]
Filtering with Conditions
# With if condition
evens = [x for x in range(20) if x % 2 == 0]
print(evens) # [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
# Filter and transform
words = ["hello", "world", "hi", "python", "a", "go"]
long_upper = [w.upper() for w in words if len(w) >= 4]
print(long_upper) # ['HELLO', 'WORLD', 'PYTHON']
# With if-else (note: different position!)
labels = ["even" if x % 2 == 0 else "odd" for x in range(6)]
print(labels) # ['even', 'odd', 'even', 'odd', 'even', 'odd']
# Multiple conditions
nums = [x for x in range(100) if x % 3 == 0 if x % 5 == 0]
print(nums) # [0, 15, 30, 45, 60, 75, 90] — divisible by both 3 and 5
# Practical: filter valid emails
emails = ["alice@example.com", "invalid", "bob@test.org", "", "bad@"]
valid = [e for e in emails if "@" in e and "." in e.split("@")[-1]]
print(valid) # ['alice@example.com', 'bob@test.org']
Nested Comprehensions
# Flatten a 2D list
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Equivalent nested for loop:
# for row in matrix:
# for num in row:
# flat.append(num)
# Create a 2D matrix
grid = [[i * j for j in range(1, 4)] for i in range(1, 4)]
print(grid) # [[1, 2, 3], [2, 4, 6], [3, 6, 9]]
# All pairs
colors = ["red", "green"]
sizes = ["S", "M", "L"]
combinations = [(c, s) for c in colors for s in sizes]
# [('red','S'), ('red','M'), ('red','L'), ('green','S'), ...]
Dictionary and Set Comprehensions
# Dictionary comprehension
squares_dict = {x: x**2 for x in range(6)}
print(squares_dict) # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Swap keys and values
original = {"a": 1, "b": 2, "c": 3}
swapped = {v: k for k, v in original.items()}
print(swapped) # {1: 'a', 2: 'b', 3: 'c'}
# Filter dictionary
scores = {"Alice": 95, "Bob": 67, "Charlie": 82, "Diana": 91}
passing = {name: score for name, score in scores.items() if score >= 80}
print(passing) # {'Alice': 95, 'Charlie': 82, 'Diana': 91}
# Set comprehension
sentence = "hello world hello python world"
unique_lengths = {len(word) for word in sentence.split()}
print(unique_lengths) # {5, 6}
Generator Expressions
# Generator expression — like list comp but lazy (memory efficient)
# Uses parentheses instead of brackets
sum_of_squares = sum(x**2 for x in range(1000000))
# Does NOT create a million-element list in memory
# Useful for large datasets
import sys
list_comp = [x**2 for x in range(10000)]
gen_expr = (x**2 for x in range(10000))
print(sys.getsizeof(list_comp)) # ~87624 bytes
print(sys.getsizeof(gen_expr)) # ~200 bytes (just the generator object)
# Can only iterate once
gen = (x for x in range(5))
print(list(gen)) # [0, 1, 2, 3, 4]
print(list(gen)) # [] — exhausted!
# Practical: process large file line by line
# total = sum(len(line) for line in open("huge_file.txt"))
Pro tip: Keep comprehensions simple and readable. If a comprehension is getting complex with multiple conditions or nested loops, break it into a regular for loop instead. The Zen of Python says "Readability counts" — a three-line for loop is better than a one-line comprehension nobody can understand.
Key Takeaways
- List comprehensions
[expr for x in iterable]provide a concise way to create lists from existing iterables. - Add
if conditionafter the iterable to filter elements; useexpr1 if cond else expr2beforeforto transform conditionally. - Dictionary (
{k: v for ...}) and set ({x for ...}) comprehensions follow the same pattern. - Generator expressions
(expr for x in iterable)are memory-efficient alternatives for large datasets. - Keep comprehensions readable — if it takes more than one line or is hard to understand at a glance, use a regular loop.