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.

example
basic.py
Replay: real traced execution (multi-file project)
# 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")
  1. 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 ===
  2. squares_loop ← [1]

    pass 1 of 5
    7squares_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
    passnsquares_loop
    11[] [1]
    22[1] [1, 4]
    33[1, 4] [1, 4, 9]
    44[1, 4, 9] [1, 4, 9, 16]
    55[1, 4, 9, 16] [1, 4, 9, 16, 25]
  3. 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 traditional
    outputLoop: [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
  1. 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 ===
  2. squares_loop ← [4]

    pass 1 of 3
    7squares_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
    passnsquares_loop
    12[] [4]
    24[4] [4, 16]
    36[4, 16] [4, 16, 36]
  3. 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
  1. 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 ===
  2. squares_loop ← [9]

    pass 1 of 4
    7squares_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
    passnsquares_loop
    13[] [9]
    26[9] [9, 36]
    39[9, 36] [9, 36, 81]
    412[9, 36, 81] [9, 36, 81, 144]
  3. 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
  1. 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 ===
  2. squares_loop ← [1]

    pass 1 of 5
    7squares_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
    passnsquares_loop
    11[] [1]
    22[1] [1, 4]
    33[1, 4] [1, 4, 9]
    44[1, 4, 9] [1, 4, 9, 16]
    55[1, 4, 9, 16] [1, 4, 9, 16, 25]
  3. 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.

list comprehension Concise list creation: `[x*2 for x in items]`. Replaces loop + append.

Filter with condition

Include only items that pass a test.

with_condition.py
Replay: real traced execution (multi-file project)
# 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")
  1. 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 even
    output=== 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.py
Replay: real traced execution (multi-file project)
# 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)")
  1. 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 ===
  2. for x in range(1, 4):

    pass 1 of 3
    6pairs_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
    passx
    11
    22
    33
  3. pairs_loop ← [(1, 1)]

    pass 1 of 9
    7for 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
    passyxpairs_loop
    111[] [(1, 1)]
    221[(1, 1)] [(1, 1), (1, 2)]
    331[(1, 1), (1, 2)] [(1, 1), (1, 2), (1, 3)]
    412[(1, 1), (1, 2), (1, 3)] [(1, 1), (1, 2), (1, 3), (2, 1)]
    522[(1, 1), (1, 2), (1, 3), (2, 1)] [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2)]
    632[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2)] [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3)]
    713[(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)]
    823[(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)]
    933[(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)]
  4. 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 ===
  5. for i, p in enumerate(products, 1):

    pass 1 of 9
    19products = [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=1
    All 9 passes — pass 1 is the card above
    passip
    111×1=1
    221×2=2
    331×3=3
    442×1=2
    552×2=4
    662×3=6
    773×1=3
    883×2=6
    993×3=9
  6. if i % 3 == 0:

    pass 1 of 3
    21print(p, end="  ")22if i3 % 3 == 0:23    print()
    All 3 passes — pass 1 is the card above
    passi
    13
    26
    39
  7. 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 traditional
    output
    === 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.

if_else.py
Replay: real traced execution (multi-file project)
# 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}")
  1. 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 label
    output=== 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.

conditional expression Ternary in comprehension: `[x if x > 0 else 0 for x in items]`.

Replace map and filter

Comprehensions are often clearer than map/filter.

replace_map_filter.py
Replay: real traced execution (multi-file project)
# 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]]}")
  1. 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 map
    output=== 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