Pythonic Patterns
List Comprehension
Concise List Creation
You need to square every number in a list. A for loop takes four lines. List
comprehension does it in one: [x**2 for x in numbers]. It's not just shorter -
it's the Pythonic way to transform sequences.
Basic transformation
Transform each element in a list.
# Basic List Comprehension
print("=== Basic List Comprehension ===\n")
# Traditional loop approach
numbers =
squares_loop = []
for n in numbers:
squares_loop.append(n ** 2)
print(f"Loop: {squares_loop}")
# List comprehension - same result!
squares_comp = [n ** 2 for n in numbers]
print(f"Comprehension: {squares_comp}")
print("\n=== More Examples ===")
# Double each number
doubled = [x * 2 for x in range(1, 6)]
print(f"Doubled 1-5: {doubled}")
# String lengths
words =
lengths = [len(w) for w in words]
print(f"Words: {words}")
print(f"Lengths: {lengths}")
# Uppercase strings
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(f"Original: {names}")
print(f"Uppercase: {upper_names}")
print("\n=== Structure ===")
print("[expression for item in iterable]")
print(" ^ ^ ^")
print(" | | +-- source of items")
print(" | +----------- loop variable")
print(" +----------------------- what to put in result")
# Basic List Comprehension
print("=== Basic List Comprehension ===\n")
# Traditional loop approach
numbers =
squares_loop = []
for n in numbers:
squares_loop.append(n ** 2)
print(f"Loop: {squares_loop}")
# List comprehension - same result!
squares_comp = [n ** 2 for n in numbers]
print(f"Comprehension: {squares_comp}")
print("\n=== More Examples ===")
# Double each number
doubled = [x * 2 for x in range(1, 6)]
print(f"Doubled 1-5: {doubled}")
# String lengths
words =
lengths = [len(w) for w in words]
print(f"Words: {words}")
print(f"Lengths: {lengths}")
# Uppercase strings
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(f"Original: {names}")
print(f"Uppercase: {upper_names}")
print("\n=== Structure ===")
print("[expression for item in iterable]")
print(" ^ ^ ^")
print(" | | +-- source of items")
print(" | +----------- loop variable")
print(" +----------------------- what to put in result")
# Basic List Comprehension
print("=== Basic List Comprehension ===\n")
# Traditional loop approach
numbers =
squares_loop = []
for n in numbers:
squares_loop.append(n ** 2)
print(f"Loop: {squares_loop}")
# List comprehension - same result!
squares_comp = [n ** 2 for n in numbers]
print(f"Comprehension: {squares_comp}")
print("\n=== More Examples ===")
# Double each number
doubled = [x * 2 for x in range(1, 6)]
print(f"Doubled 1-5: {doubled}")
# String lengths
words =
lengths = [len(w) for w in words]
print(f"Words: {words}")
print(f"Lengths: {lengths}")
# Uppercase strings
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(f"Original: {names}")
print(f"Uppercase: {upper_names}")
print("\n=== Structure ===")
print("[expression for item in iterable]")
print(" ^ ^ ^")
print(" | | +-- source of items")
print(" | +----------- loop variable")
print(" +----------------------- what to put in result")
# Basic List Comprehension
print("=== Basic List Comprehension ===\n")
# Traditional loop approach
numbers =
squares_loop = []
for n in numbers:
squares_loop.append(n ** 2)
print(f"Loop: {squares_loop}")
# List comprehension - same result!
squares_comp = [n ** 2 for n in numbers]
print(f"Comprehension: {squares_comp}")
print("\n=== More Examples ===")
# Double each number
doubled = [x * 2 for x in range(1, 6)]
print(f"Doubled 1-5: {doubled}")
# String lengths
words =
lengths = [len(w) for w in words]
print(f"Words: {words}")
print(f"Lengths: {lengths}")
# Uppercase strings
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(f"Original: {names}")
print(f"Uppercase: {upper_names}")
print("\n=== Structure ===")
print("[expression for item in iterable]")
print(" ^ ^ ^")
print(" | | +-- source of items")
print(" | +----------- loop variable")
print(" +----------------------- what to put in result")
# Basic List Comprehension
print("=== Basic List Comprehension ===\n")
# Traditional loop approach
numbers =
squares_loop = []
for n in numbers:
squares_loop.append(n ** 2)
print(f"Loop: {squares_loop}")
# List comprehension - same result!
squares_comp = [n ** 2 for n in numbers]
print(f"Comprehension: {squares_comp}")
print("\n=== More Examples ===")
# Double each number
doubled = [x * 2 for x in range(1, 6)]
print(f"Doubled 1-5: {doubled}")
# String lengths
words =
lengths = [len(w) for w in words]
print(f"Words: {words}")
print(f"Lengths: {lengths}")
# Uppercase strings
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(f"Original: {names}")
print(f"Uppercase: {upper_names}")
print("\n=== Structure ===")
print("[expression for item in iterable]")
print(" ^ ^ ^")
print(" | | +-- source of items")
print(" | +----------- loop variable")
print(" +----------------------- what to put in result")
# Basic List Comprehension
print("=== Basic List Comprehension ===\n")
# Traditional loop approach
numbers =
squares_loop = []
for n in numbers:
squares_loop.append(n ** 2)
print(f"Loop: {squares_loop}")
# List comprehension - same result!
squares_comp = [n ** 2 for n in numbers]
print(f"Comprehension: {squares_comp}")
print("\n=== More Examples ===")
# Double each number
doubled = [x * 2 for x in range(1, 6)]
print(f"Doubled 1-5: {doubled}")
# String lengths
words =
lengths = [len(w) for w in words]
print(f"Words: {words}")
print(f"Lengths: {lengths}")
# Uppercase strings
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
print(f"Original: {names}")
print(f"Uppercase: {upper_names}")
print("\n=== Structure ===")
print("[expression for item in iterable]")
print(" ^ ^ ^")
print(" | | +-- source of items")
print(" | +----------- loop variable")
print(" +----------------------- what to put in result")
[expression for item in iterable] - the expression is applied to each item.
Filter with condition
Include only items that pass a test.
# List Comprehension with Conditions
print("=== Filtering with Conditions ===\n")
numbers = list(range(1, 11))
print(f"Original: {numbers}")
# Only even numbers
evens = [n for n in numbers if n % 2 == 0]
print(f"Evens: {evens}")
# Only odd numbers
odds = [n for n in numbers if n % 2 != 0]
print(f"Odds: {odds}")
print("\n=== Multiple Conditions ===")
# Numbers divisible by 2 AND 3
div_by_2_and_3 = [n for n in range(1, 31) if n % 2 == 0 if n % 3 == 0]
print(f"Divisible by 2 AND 3 (1-30): {div_by_2_and_3}")
# Same with 'and'
div_by_2_and_3_v2 = [n for n in range(1, 31) if n % 2 == 0 and n % 3 == 0]
print(f"Same with 'and': {div_by_2_and_3_v2}")
print("\n=== String Filtering ===")
words = ["apple", "ant", "banana", "avocado", "berry", "apricot"]
print(f"Words: {words}")
# Words starting with 'a'
a_words = [w for w in words if w.startswith('a')]
print(f"Start with 'a': {a_words}")
# Words longer than 5 characters
long_words = [w for w in words if len(w) > 5]
print(f"Longer than 5: {long_words}")
# Combined: starts with 'a' AND longer than 4
a_long = [w for w in words if w.startswith('a') and len(w) > 4]
print(f"Start 'a' AND len > 4: {a_long}")
print("\n=== Structure ===")
print("[expression for item in iterable if condition]")
print(" ^^^^^^^^^^^^")
print(" Filter: only items where condition is True")
Add if condition at the end to filter: [x for x in items if x > 0].
Nested comprehensions
Handle nested loops in comprehensions.
# Nested List Comprehensions
print("=== Nested Loops in Comprehensions ===\n")
# Traditional nested loop
pairs_loop = []
for x in range(1, 4):
for y in range(1, 4):
pairs_loop.append((x, y))
print(f"Loop pairs: {pairs_loop}")
# Nested comprehension
pairs_comp = [(x, y) for x in range(1, 4) for y in range(1, 4)]
print(f"Comp pairs: {pairs_comp}")
print("\n=== Multiplication Table ===")
# 3x3 multiplication combinations
products = [f"{x}×{y}={x*y}" for x in range(1, 4) for y in range(1, 4)]
for i, p in enumerate(products, 1):
print(p, end=" ")
if i % 3 == 0:
print()
print("\n=== Flattening Lists ===")
# 2D list (list of lists)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(f"Matrix: {matrix}")
# Flatten to 1D
flat = [num for row in matrix for num in row]
print(f"Flattened: {flat}")
print("\n=== With Conditions ===")
# Pairs where x != y
no_same = [(x, y) for x in range(1, 4) for y in range(1, 4) if x != y]
print(f"Pairs (x != y): {no_same}")
# Pairs where x < y (no duplicates)
ordered = [(x, y) for x in range(1, 5) for y in range(1, 5) if x < y]
print(f"Pairs (x < y): {ordered}")
print("\n=== Reading Order ===")
print("[ expr for outer in iterable1 for inner in iterable2 ]")
print(" ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^")
print(" First (outer loop) Second (inner loop)")
[x for row in matrix for x in row] flattens nested structures.
Conditional expression (if-else)
Choose between values based on condition.
# List Comprehension with if-else
print("=== Conditional Expressions (if-else) ===\n")
numbers = list(range(1, 11))
print(f"Numbers: {numbers}")
# Label each number
labels = ["even" if n % 2 == 0 else "odd" for n in numbers]
print(f"Labels: {labels}")
print("\n=== Different Position! ===")
print("Filter (if only): [x for x in items if condition]")
print("Transform (if-else): [a if cond else b for x in items]")
print("\n=== Transform Values ===")
# Cap values at 5
capped = [n if n <= 5 else 5 for n in numbers]
print(f"Capped at 5: {capped}")
# Absolute values
mixed = [-3, -1, 0, 2, 4, -5]
absolute = [x if x >= 0 else -x for x in mixed]
print(f"Original: {mixed}")
print(f"Absolute: {absolute}")
print("\n=== String Transformations ===")
words = ["hello", "WORLD", "PyThOn"]
# Normalize: if uppercase, keep; else uppercase
normalized = [w if w.isupper() else w.upper() for w in words]
print(f"Original: {words}")
print(f"Normalized: {normalized}")
# First letter uppercase, rest lowercase
capitalized = [w.capitalize() for w in words]
print(f"Capitalized: {capitalized}")
print("\n=== Combining Filter and Transform ===")
# Filter AND transform
# Keep evens, but square them
even_squares = [n ** 2 for n in numbers if n % 2 == 0]
print(f"Even numbers squared: {even_squares}")
# Different value based on condition (no filter)
signs = ["+" if n > 0 else ("-" if n < 0 else "0") for n in [-2, -1, 0, 1, 2]]
print(f"Signs of [-2,-1,0,1,2]: {signs}")
[a if cond else b for x in items] - the if-else goes before for.
Replace map and filter
Comprehensions are often clearer than map/filter.
# Replacing map() and filter()
print("=== List Comprehension vs map()/filter() ===\n")
numbers = [1, 2, 3, 4, 5]
print(f"Numbers: {numbers}")
# --- map() replacement ---
# Using map()
squared_map = list(map(lambda x: x ** 2, numbers))
print(f"map() squares: {squared_map}")
# Using comprehension
squared_comp = [x ** 2 for x in numbers]
print(f"Comprehension squares: {squared_comp}")
print("\n=== filter() Replacement ===")
# Using filter()
evens_filter = list(filter(lambda x: x % 2 == 0, numbers))
print(f"filter() evens: {evens_filter}")
# Using comprehension
evens_comp = [x for x in numbers if x % 2 == 0]
print(f"Comprehension evens: {evens_comp}")
print("\n=== Combined map() + filter() ===")
# Square only even numbers
# Using map + filter
result_func = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers)))
print(f"map+filter: {result_func}")
# Using comprehension
result_comp = [x ** 2 for x in numbers if x % 2 == 0]
print(f"Comprehension: {result_comp}")
print("\n=== Which to Use? ===")
# Comprehension advantages:
print("Comprehension:")
print(" ✓ More readable (Pythonic)")
print(" ✓ No lambda needed")
print(" ✓ Can combine filter + transform")
# map()/filter() advantages:
print("\nmap()/filter():")
print(" ✓ Can use existing named functions")
print(" ✓ Lazy evaluation with iterators")
# Example with named function
def double(x): return x * 2
# Both work, but map more natural here
print(f"\nmap(double, [1,2,3]): {list(map(double, [1,2,3]))}")
print(f"[double(x) for x in [1,2,3]]: {[double(x) for x in [1,2,3]]}")
[f(x) for x in items] replaces map(). Add if to replace filter().
Exercise: practical.py
Real-world list comprehension patterns