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 = [1, 2, 3, 4, 5]
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 = ["apple", "pie", "delicious"]
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 = [2, 4, 6]
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 = ["apple", "pie", "delicious"]
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 = [3, 6, 9, 12]
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 = ["apple", "pie", "delicious"]
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 = [1, 2, 3, 4, 5]
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 = ["sun", "moon", "stars"]
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")
numbers ← [1, 2, 3, 4, 5], squares_loop ← []
3print("=== Basic List Comprehension ===\n")45# Traditional loop approach #?traditional6numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5] #@numbers=[2, 4, 6], [3, 6, 9, 12]7squares_loop→ [] = []8for n in numbers:output=== Basic List Comprehension ===squares_loop ← [1]
pass 1 of 57squares_loop = []8for n1 in numbers[1, 2, 3, 4, 5]:9 squares_loop→ [1].append(n1 ** 2)10print(f"Loop: {squares_loop}")All 5 passes — pass 1 is the card above pass nsquares_loop1 1 [] → [1] 2 2 [1] → [1, 4] 3 3 [1, 4] → [1, 4, 9] 4 4 [1, 4, 9] → [1, 4, 9, 16] 5 5 [1, 4, 9, 16] → [1, 4, 9, 16, 25] squares_comp ← [1, 4, 9, 16, 25], doubled ← [2, 4, 6, 8, 10], words ← ['apple', 'pie', 'delicious']
9 squares_loop.append(n ** 2)10print(f"Loop: {squares_loop[1, 4, 9, 16, 25]}")1112# List comprehension - same result! #?comprehension13squares_comp→ [1, 4, 9, 16, 25] = [n ** 2 for n in numbers[1, 2, 3, 4, 5]]14print(f"Comprehension: {squares_comp[1, 4, 9, 16, 25]}")1516print("\n=== More Examples ===")1718# Double each number #?double19doubled→ [2, 4, 6, 8, 10] = [x * 2 for x in range(1, 6)]20print(f"Doubled 1-5: {doubled[2, 4, 6, 8, 10]}")2122# String lengths #?strlen23words→ ['apple', 'pie', 'delicious'] = ["apple", "pie", "delicious"] #@words=["sun", "moon", "stars"]24lengths→ [5, 3, 9] = [len(w) for w in words['apple', 'pie', 'delicious']] #?lencomp25print(f"Words: {words['apple', 'pie', 'delicious']}")26print(f"Lengths: {lengths[5, 3, 9]}")2728# Uppercase strings #?upper29names→ ['alice', 'bob', 'charlie'] = ["alice", "bob", "charlie"]30upper_names→ ['ALICE', 'BOB', 'CHARLIE'] = [name.upper() for name in names['alice', 'bob', 'charlie']]31print(f"Original: {names['alice', 'bob', 'charlie']}")32print(f"Uppercase: {upper_names['ALICE', 'BOB', 'CHARLIE']}")3334print("\n=== Structure ===")35print("[expression for item in iterable]")36print(" ^ ^ ^")37print(" | | +-- source of items")38print(" | +----------- loop variable")39print(" +----------------------- what to put in result")40#@help traditionaloutputLoop: [1, 4, 9, 16, 25] Comprehension: [1, 4, 9, 16, 25] === More Examples === Doubled 1-5: [2, 4, 6, 8, 10] Words: ['apple', 'pie', 'delicious'] Lengths: [5, 3, 9] Original: ['alice', 'bob', 'charlie'] Uppercase: ['ALICE', 'BOB', 'CHARLIE'] === Structure === [expression for item in iterable] ^ ^ ^ | | +-- source of items | +----------- loop variable +----------------------- what to put in result
numbers ← [2, 4, 6], squares_loop ← []
3print("=== Basic List Comprehension ===\n")45# Traditional loop approach6numbers→ [2, 4, 6] = [2, 4, 6]7squares_loop→ [] = []8for n in numbers:output=== Basic List Comprehension ===squares_loop ← [4]
pass 1 of 37squares_loop = []8for n2 in numbers[2, 4, 6]:9 squares_loop→ [4].append(n2 ** 2)10print(f"Loop: {squares_loop}")All 3 passes — pass 1 is the card above pass nsquares_loop1 2 [] → [4] 2 4 [4] → [4, 16] 3 6 [4, 16] → [4, 16, 36] squares_comp ← [4, 16, 36], doubled ← [2, 4, 6, 8, 10], words ← ['apple', 'pie', 'delicious']
9 squares_loop.append(n ** 2)10print(f"Loop: {squares_loop[4, 16, 36]}")1112# List comprehension - same result!13squares_comp→ [4, 16, 36] = [n ** 2 for n in numbers[2, 4, 6]]14print(f"Comprehension: {squares_comp[4, 16, 36]}")1516print("\n=== More Examples ===")1718# Double each number19doubled→ [2, 4, 6, 8, 10] = [x * 2 for x in range(1, 6)]20print(f"Doubled 1-5: {doubled[2, 4, 6, 8, 10]}")2122# String lengths23words→ ['apple', 'pie', 'delicious'] = ["apple", "pie", "delicious"]24lengths→ [5, 3, 9] = [len(w) for w in words['apple', 'pie', 'delicious']]25print(f"Words: {words['apple', 'pie', 'delicious']}")26print(f"Lengths: {lengths[5, 3, 9]}")2728# Uppercase strings29names→ ['alice', 'bob', 'charlie'] = ["alice", "bob", "charlie"]30upper_names→ ['ALICE', 'BOB', 'CHARLIE'] = [name.upper() for name in names['alice', 'bob', 'charlie']]31print(f"Original: {names['alice', 'bob', 'charlie']}")32print(f"Uppercase: {upper_names['ALICE', 'BOB', 'CHARLIE']}")3334print("\n=== Structure ===")35print("[expression for item in iterable]")36print(" ^ ^ ^")37print(" | | +-- source of items")38print(" | +----------- loop variable")39print(" +----------------------- what to put in result")outputLoop: [4, 16, 36] Comprehension: [4, 16, 36] === More Examples === Doubled 1-5: [2, 4, 6, 8, 10] Words: ['apple', 'pie', 'delicious'] Lengths: [5, 3, 9] Original: ['alice', 'bob', 'charlie'] Uppercase: ['ALICE', 'BOB', 'CHARLIE'] === Structure === [expression for item in iterable] ^ ^ ^ | | +-- source of items | +----------- loop variable +----------------------- what to put in result
numbers ← [3, 6, 9, 12], squares_loop ← []
3print("=== Basic List Comprehension ===\n")45# Traditional loop approach6numbers→ [3, 6, 9, 12] = [3, 6, 9, 12]7squares_loop→ [] = []8for n in numbers:output=== Basic List Comprehension ===squares_loop ← [9]
pass 1 of 47squares_loop = []8for n3 in numbers[3, 6, 9, 12]:9 squares_loop→ [9].append(n3 ** 2)10print(f"Loop: {squares_loop}")All 4 passes — pass 1 is the card above pass nsquares_loop1 3 [] → [9] 2 6 [9] → [9, 36] 3 9 [9, 36] → [9, 36, 81] 4 12 [9, 36, 81] → [9, 36, 81, 144] squares_comp ← [9, 36, 81, 144], doubled ← [2, 4, 6, 8, 10], words ← ['apple', 'pie', 'delicious']
9 squares_loop.append(n ** 2)10print(f"Loop: {squares_loop[9, 36, 81, 144]}")1112# List comprehension - same result!13squares_comp→ [9, 36, 81, 144] = [n ** 2 for n in numbers[3, 6, 9, 12]]14print(f"Comprehension: {squares_comp[9, 36, 81, 144]}")1516print("\n=== More Examples ===")1718# Double each number19doubled→ [2, 4, 6, 8, 10] = [x * 2 for x in range(1, 6)]20print(f"Doubled 1-5: {doubled[2, 4, 6, 8, 10]}")2122# String lengths23words→ ['apple', 'pie', 'delicious'] = ["apple", "pie", "delicious"]24lengths→ [5, 3, 9] = [len(w) for w in words['apple', 'pie', 'delicious']]25print(f"Words: {words['apple', 'pie', 'delicious']}")26print(f"Lengths: {lengths[5, 3, 9]}")2728# Uppercase strings29names→ ['alice', 'bob', 'charlie'] = ["alice", "bob", "charlie"]30upper_names→ ['ALICE', 'BOB', 'CHARLIE'] = [name.upper() for name in names['alice', 'bob', 'charlie']]31print(f"Original: {names['alice', 'bob', 'charlie']}")32print(f"Uppercase: {upper_names['ALICE', 'BOB', 'CHARLIE']}")3334print("\n=== Structure ===")35print("[expression for item in iterable]")36print(" ^ ^ ^")37print(" | | +-- source of items")38print(" | +----------- loop variable")39print(" +----------------------- what to put in result")outputLoop: [9, 36, 81, 144] Comprehension: [9, 36, 81, 144] === More Examples === Doubled 1-5: [2, 4, 6, 8, 10] Words: ['apple', 'pie', 'delicious'] Lengths: [5, 3, 9] Original: ['alice', 'bob', 'charlie'] Uppercase: ['ALICE', 'BOB', 'CHARLIE'] === Structure === [expression for item in iterable] ^ ^ ^ | | +-- source of items | +----------- loop variable +----------------------- what to put in result
numbers ← [1, 2, 3, 4, 5], squares_loop ← []
3print("=== Basic List Comprehension ===\n")45# Traditional loop approach6numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]7squares_loop→ [] = []8for n in numbers:output=== Basic List Comprehension ===squares_loop ← [1]
pass 1 of 57squares_loop = []8for n1 in numbers[1, 2, 3, 4, 5]:9 squares_loop→ [1].append(n1 ** 2)10print(f"Loop: {squares_loop}")All 5 passes — pass 1 is the card above pass nsquares_loop1 1 [] → [1] 2 2 [1] → [1, 4] 3 3 [1, 4] → [1, 4, 9] 4 4 [1, 4, 9] → [1, 4, 9, 16] 5 5 [1, 4, 9, 16] → [1, 4, 9, 16, 25] squares_comp ← [1, 4, 9, 16, 25], doubled ← [2, 4, 6, 8, 10], words ← ['sun', 'moon', 'stars']
9 squares_loop.append(n ** 2)10print(f"Loop: {squares_loop[1, 4, 9, 16, 25]}")1112# List comprehension - same result!13squares_comp→ [1, 4, 9, 16, 25] = [n ** 2 for n in numbers[1, 2, 3, 4, 5]]14print(f"Comprehension: {squares_comp[1, 4, 9, 16, 25]}")1516print("\n=== More Examples ===")1718# Double each number19doubled→ [2, 4, 6, 8, 10] = [x * 2 for x in range(1, 6)]20print(f"Doubled 1-5: {doubled[2, 4, 6, 8, 10]}")2122# String lengths23words→ ['sun', 'moon', 'stars'] = ["sun", "moon", "stars"]24lengths→ [3, 4, 5] = [len(w) for w in words['sun', 'moon', 'stars']]25print(f"Words: {words['sun', 'moon', 'stars']}")26print(f"Lengths: {lengths[3, 4, 5]}")2728# Uppercase strings29names→ ['alice', 'bob', 'charlie'] = ["alice", "bob", "charlie"]30upper_names→ ['ALICE', 'BOB', 'CHARLIE'] = [name.upper() for name in names['alice', 'bob', 'charlie']]31print(f"Original: {names['alice', 'bob', 'charlie']}")32print(f"Uppercase: {upper_names['ALICE', 'BOB', 'CHARLIE']}")3334print("\n=== Structure ===")35print("[expression for item in iterable]")36print(" ^ ^ ^")37print(" | | +-- source of items")38print(" | +----------- loop variable")39print(" +----------------------- what to put in result")outputLoop: [1, 4, 9, 16, 25] Comprehension: [1, 4, 9, 16, 25] === More Examples === Doubled 1-5: [2, 4, 6, 8, 10] Words: ['sun', 'moon', 'stars'] Lengths: [3, 4, 5] Original: ['alice', 'bob', 'charlie'] Uppercase: ['ALICE', 'BOB', 'CHARLIE'] === Structure === [expression for item in iterable] ^ ^ ^ | | +-- source of items | +----------- loop variable +----------------------- 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")
numbers ← [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], evens ← [2, 4, 6, 8, 10]
3print("=== Filtering with Conditions ===\n")45numbers→ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] = list(range(1, 11))6print(f"Original: {numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}")78# Only even numbers #?even9evens→ [2, 4, 6, 8, 10] = [n for n in numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] if n % 2 == 0] #?ifcondition10print(f"Evens: {evens[2, 4, 6, 8, 10]}")1112# Only odd numbers13odds→ [1, 3, 5, 7, 9] = [n for n in numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] if n % 2 != 0]14print(f"Odds: {odds[1, 3, 5, 7, 9]}")1516print("\n=== Multiple Conditions ===")1718# Numbers divisible by 2 AND 3 #?multiple19div_by_2_and_3→ [6, 12, 18, 24, 30] = [n for n in range(1, 31) if n % 2 == 0 if n % 3 == 0] #?multipleif20print(f"Divisible by 2 AND 3 (1-30): {div_by_2_and_3[6, 12, 18, 24, 30]}")2122# Same with 'and' #?andversion23div_by_2_and_3_v2→ [6, 12, 18, 24, 30] = [n for n in range(1, 31) if n % 2 == 0 and n % 3 == 0]24print(f"Same with 'and': {div_by_2_and_3_v2[6, 12, 18, 24, 30]}")2526print("\n=== String Filtering ===")2728words→ ['apple', 'ant', 'banana', 'avocado', 'berry', 'apricot'] = ["apple", "ant", "banana", "avocado", "berry", "apricot"] #?stringfilter29print(f"Words: {words['apple', 'ant', 'banana', 'avocado', 'berry', 'apricot']}")3031# Words starting with 'a'32a_words→ ['apple', 'ant', 'avocado', 'apricot'] = [w for w in words['apple', 'ant', 'banana', 'avocado', 'berry', 'apricot'] if w.startswith('a')]33print(f"Start with 'a': {a_words['apple', 'ant', 'avocado', 'apricot']}")3435# Words longer than 5 characters36long_words→ ['banana', 'avocado', 'apricot'] = [w for w in words['apple', 'ant', 'banana', 'avocado', 'berry', 'apricot'] if len(w) > 5]37print(f"Longer than 5: {long_words['banana', 'avocado', 'apricot']}")3839# Combined: starts with 'a' AND longer than 4 #?combined40a_long→ ['apple', 'avocado', 'apricot'] = [w for w in words['apple', 'ant', 'banana', 'avocado', 'berry', 'apricot'] if w.startswith('a') and len(w) > 4]41print(f"Start 'a' AND len > 4: {a_long['apple', 'avocado', 'apricot']}")4243print("\n=== Structure ===")44print("[expression for item in iterable if condition]")45print(" ^^^^^^^^^^^^")46print(" Filter: only items where condition is True")47#@help evenoutput=== Filtering with Conditions === Original: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Evens: [2, 4, 6, 8, 10] Odds: [1, 3, 5, 7, 9] === Multiple Conditions === Divisible by 2 AND 3 (1-30): [6, 12, 18, 24, 30] Same with 'and': [6, 12, 18, 24, 30] === String Filtering === Words: ['apple', 'ant', 'banana', 'avocado', 'berry', 'apricot'] Start with 'a': ['apple', 'ant', 'avocado', 'apricot'] Longer than 5: ['banana', 'avocado', 'apricot'] Start 'a' AND len > 4: ['apple', 'avocado', 'apricot'] === Structure === [expression for item in iterable if condition] ^^^^^^^^^^^^ 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)")
pairs_loop ← []
3print("=== Nested Loops in Comprehensions ===\n")45# Traditional nested loop #?traditional6pairs_loop→ [] = []7for x in range(1, 4):output=== Nested Loops in Comprehensions ===for x in range(1, 4):
pass 1 of 36pairs_loop = []7for x1 in range(1, 4):8 for y in range(1, 4):9 pairs_loop.append((x, y))All 3 passes — pass 1 is the card above pass x1 1 2 2 3 3 pairs_loop ← [(1, 1)]
pass 1 of 97for x in range(1, 4):8 for y1 in range(1, 4):9 pairs_loop→ [(1, 1)].append((x1, y1))10print(f"Loop pairs: {pairs_loop}")All 9 passes — pass 1 is the card above pass yxpairs_loop1 1 1 [] → [(1, 1)] 2 2 1 [(1, 1)] → [(1, 1), (1, 2)] 3 3 1 [(1, 1), (1, 2)] → [(1, 1), (1, 2), (1, 3)] 4 1 2 [(1, 1), (1, 2), (1, 3)] → [(1, 1), (1, 2), (1, 3), (2, 1)] 5 2 2 [(1, 1), (1, 2), (1, 3), (2, 1)] → [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2)] 6 3 2 [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2)] → [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)] 7 1 3 [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)] → [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1)] 8 2 3 [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1)] → [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2)] 9 3 3 [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2)] → [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] pairs_comp ← [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]
9 pairs_loop.append((x, y))10print(f"Loop pairs: {pairs_loop[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]}")1112# Nested comprehension #?nested13pairs_comp→ [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] = [(x, y) for x in range(1, 4) for y in range(1, 4)] #?nestedcomp14print(f"Comp pairs: {pairs_comp[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]}")1516print("\n=== Multiplication Table ===")1718# 3x3 multiplication combinations #?mult19products→ ['1×1=1', '1×2=2', '1×3=3', '2×1=2', '2×2=4', '2×3=6', '3×1=3', '3×2=6', '3×3=9'] = [f"{x}×{y}={x*y}" for x in range(1, 4) for y in range(1, 4)]20for i, p in enumerate(products, 1):outputLoop pairs: [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] Comp pairs: [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)] === Multiplication Table ===for i, p in enumerate(products, 1):
pass 1 of 919products = [f"{x}×{y}={x*y}" for x in range(1, 4) for y in range(1, 4)]20for i1, p1×1=1 in enumerate(products['1×1=1', '1×2=2', '1×3=3', '2×1=2', '2×2=4', '2×3=6', '3×1=3', '3×2=6', '3×3=9'], 1):21 print(p1×1=1, end=" ")22 if i % 3 == 0:output1×1=1All 9 passes — pass 1 is the card above pass ip1 1 1×1=1 2 2 1×2=2 3 3 1×3=3 4 4 2×1=2 5 5 2×2=4 6 6 2×3=6 7 7 3×1=3 8 8 3×2=6 9 9 3×3=9 if i % 3 == 0:
pass 1 of 321print(p, end=" ")22if i3 % 3 == 0:23 print()All 3 passes — pass 1 is the card above pass i1 3 2 6 3 9 matrix ← [[1, 2, 3], [4, 5, 6], [7, 8, 9]], flat ← [1, 2, 3, 4, 5, 6, 7, 8, 9]
25print("\n=== Flattening Lists ===")2627# 2D list (list of lists) #?flatten28matrix→ [[1, 2, 3], [4, 5, 6], [7, 8, 9]] = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]29print(f"Matrix: {matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]}")3031# Flatten to 1D32flat→ [1, 2, 3, 4, 5, 6, 7, 8, 9] = [num for row in matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]] for num in row] #?flatcomp33print(f"Flattened: {flat[1, 2, 3, 4, 5, 6, 7, 8, 9]}")3435print("\n=== With Conditions ===")3637# Pairs where x != y #?withcond38no_same→ [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)] = [(x, y) for x in range(1, 4) for y in range(1, 4) if x != y]39print(f"Pairs (x != y): {no_same[(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]}")4041# Pairs where x < y (no duplicates)42ordered→ [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] = [(x, y) for x in range(1, 5) for y in range(1, 5) if x < y] #?ordered43print(f"Pairs (x < y): {ordered[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]}")4445print("\n=== Reading Order ===")46print("[ expr for outer in iterable1 for inner in iterable2 ]")47print(" ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^")48print(" First (outer loop) Second (inner loop)")49#@help traditionaloutput === Flattening Lists === Matrix: [[1, 2, 3], [4, 5, 6], [7, 8, 9]] Flattened: [1, 2, 3, 4, 5, 6, 7, 8, 9] === With Conditions === Pairs (x != y): [(1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)] Pairs (x < y): [(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)] === Reading Order === [ expr for outer in iterable1 for inner in iterable2 ] ^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^ 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}")
numbers ← [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], labels ← ['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even']
3print("=== Conditional Expressions (if-else) ===\n")45numbers→ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] = list(range(1, 11))6print(f"Numbers: {numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]}")78# Label each number #?label9labels→ ['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even'] = ["even" if n % 2 == 0 else "odd" for n in numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]] #?ifelse10print(f"Labels: {labels['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even']}")1112print("\n=== Different Position! ===")13print("Filter (if only): [x for x in items if condition]")14print("Transform (if-else): [a if cond else b for x in items]")1516print("\n=== Transform Values ===")1718# Cap values at 5 #?cap19capped→ [1, 2, 3, 4, 5, 5, 5, 5, 5, 5] = [n if n <= 5 else 5 for n in numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]20print(f"Capped at 5: {capped[1, 2, 3, 4, 5, 5, 5, 5, 5, 5]}")2122# Absolute values #?abs23mixed→ [-3, -1, 0, 2, 4, -5] = [-3, -1, 0, 2, 4, -5]24absolute→ [3, 1, 0, 2, 4, 5] = [x if x >= 0 else -x for x in mixed[-3, -1, 0, 2, 4, -5]] #?abscomp25print(f"Original: {mixed[-3, -1, 0, 2, 4, -5]}")26print(f"Absolute: {absolute[3, 1, 0, 2, 4, 5]}")2728print("\n=== String Transformations ===")2930words→ ['hello', 'WORLD', 'PyThOn'] = ["hello", "WORLD", "PyThOn"] #?strings31# Normalize: if uppercase, keep; else uppercase32normalized→ ['HELLO', 'WORLD', 'PYTHON'] = [w if w.isupper() else w.upper() for w in words['hello', 'WORLD', 'PyThOn']]33print(f"Original: {words['hello', 'WORLD', 'PyThOn']}")34print(f"Normalized: {normalized['HELLO', 'WORLD', 'PYTHON']}")3536# First letter uppercase, rest lowercase37capitalized→ ['Hello', 'World', 'Python'] = [w.capitalize() for w in words['hello', 'WORLD', 'PyThOn']]38print(f"Capitalized: {capitalized['Hello', 'World', 'Python']}")3940print("\n=== Combining Filter and Transform ===")4142# Filter AND transform #?both43# Keep evens, but square them44even_squares→ [4, 16, 36, 64, 100] = [n ** 2 for n in numbers[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] if n % 2 == 0] #?filterthen45print(f"Even numbers squared: {even_squares[4, 16, 36, 64, 100]}")4647# Different value based on condition (no filter)48signs→ ['-', '-', '0', '+', '+'] = ["+" if n > 0 else ("-" if n < 0 else "0") for n in [-2, -1, 0, 1, 2]] #?nested49print(f"Signs of [-2,-1,0,1,2]: {signs['-', '-', '0', '+', '+']}")50#@help labeloutput=== Conditional Expressions (if-else) === Numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Labels: ['odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even', 'odd', 'even'] === Different Position! === Filter (if only): [x for x in items if condition] Transform (if-else): [a if cond else b for x in items] === Transform Values === Capped at 5: [1, 2, 3, 4, 5, 5, 5, 5, 5, 5] Original: [-3, -1, 0, 2, 4, -5] Absolute: [3, 1, 0, 2, 4, 5] === String Transformations === Original: ['hello', 'WORLD', 'PyThOn'] Normalized: ['HELLO', 'WORLD', 'PYTHON'] Capitalized: ['Hello', 'World', 'Python'] === Combining Filter and Transform === Even numbers squared: [4, 16, 36, 64, 100] Signs of [-2,-1,0,1,2]: ['-', '-', '0', '+', '+']
[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]]}")
numbers ← [1, 2, 3, 4, 5], squared_map ← [1, 4, 9, 16, 25], squared_comp ← [1, 4, 9, 16, 25]
3print("=== List Comprehension vs map()/filter() ===\n")45numbers→ [1, 2, 3, 4, 5] = [1, 2, 3, 4, 5]6print(f"Numbers: {numbers[1, 2, 3, 4, 5]}")78# --- map() replacement --- #?map910# Using map() #?mapfunc11squared_map→ [1, 4, 9, 16, 25] = list(map(lambda x: x ** 2, numbers[1, 2, 3, 4, 5]))12print(f"map() squares: {squared_map[1, 4, 9, 16, 25]}")1314# Using comprehension #?mapcomp15squared_comp→ [1, 4, 9, 16, 25] = [x ** 2 for x in numbers[1, 2, 3, 4, 5]]16print(f"Comprehension squares: {squared_comp[1, 4, 9, 16, 25]}")1718print("\n=== filter() Replacement ===") #?filter1920# Using filter() #?filterfunc21evens_filter→ [2, 4] = list(filter(lambda x: x % 2 == 0, numbers[1, 2, 3, 4, 5]))22print(f"filter() evens: {evens_filter[2, 4]}")2324# Using comprehension #?filtercomp25evens_comp→ [2, 4] = [x for x in numbers[1, 2, 3, 4, 5] if x % 2 == 0]26print(f"Comprehension evens: {evens_comp[2, 4]}")2728print("\n=== Combined map() + filter() ===") #?combined2930# Square only even numbers31# Using map + filter #?mapfilter32result_func→ [4, 16] = list(map(lambda x: x ** 2, filter(lambda x: x % 2 == 0, numbers[1, 2, 3, 4, 5])))33print(f"map+filter: {result_func[4, 16]}")3435# Using comprehension #?combcomp36result_comp→ [4, 16] = [x ** 2 for x in numbers[1, 2, 3, 4, 5] if x % 2 == 0]37print(f"Comprehension: {result_comp[4, 16]}")3839print("\n=== Which to Use? ===")4041# Comprehension advantages: #?advantages42print("Comprehension:")43print(" ✓ More readable (Pythonic)")44print(" ✓ No lambda needed")45print(" ✓ Can combine filter + transform")4647# map()/filter() advantages:48print("\nmap()/filter():")49print(" ✓ Can use existing named functions")50print(" ✓ Lazy evaluation with iterators")5152# Example with named function #?named53def double(x): return x * 25455# Both work, but map more natural here56print(f"\nmap(double, [1,2,3]): {list(map(double⟨function double A⟩, [1,2,3]))}")57print(f"[double(x) for x in [1,2,3]]: {[double(x) for x in [1,2,3]]}")58#@help mapoutput=== List Comprehension vs map()/filter() === Numbers: [1, 2, 3, 4, 5] map() squares: [1, 4, 9, 16, 25] Comprehension squares: [1, 4, 9, 16, 25] === filter() Replacement === filter() evens: [2, 4] Comprehension evens: [2, 4] === Combined map() + filter() === map+filter: [4, 16] Comprehension: [4, 16] === Which to Use? === Comprehension: ✓ More readable (Pythonic) ✓ No lambda needed ✓ Can combine filter + transform map()/filter(): ✓ Can use existing named functions ✓ Lazy evaluation with iterators map(double, [1,2,3]): [2, 4, 6] [double(x) for x in [1,2,3]]: [2, 4, 6]
[f(x) for x in items] replaces map(). Add if to replace filter().
Exercise: practical.py
Real-world list comprehension patterns