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.py
# 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.

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
# 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.py
# 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.

if_else.py
# 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.

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
# 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