🕯️ Magic Note
Creating new lists from existing ones is called “transformation” or “mapping”. When you also skip some items, it is called “filtering”. Together, transformation and filtering are the foundation of data processing. Python’s list comprehensions combine both in a single, readable line.
Python
# Double each number in a list
numbers = [1, 2, 3, 4, 5]
doubled = []
for num in numbers:
doubled.append(num * 2)
print(doubled) # [2, 4, 6, 8, 10]
Python
# Basic list comprehension
numbers = [1, 2, 3, 4, 5]
doubled = [num * 2 for num in numbers]
print(doubled) # [2, 4, 6, 8, 10]
# Read as: “doubled is a list of num*2 for each num in numbers”
🕯️ Magic Note
List comprehensions are not just shorter. They are also faster than for loops with .append() because the append operation happens internally at C speed rather than Python speed. For large lists, this difference matters.
Python
# Even numbers only
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [num for num in numbers if num % 2 == 0]
print(evens) # [2, 4, 6, 8, 10]
# Long names only
names = [“Ali”, “Sara”, “Reza”, “Feloriya”, “Mina”, “Alexander”]
long_names = [name for name in names if len(name) > 4]
print(long_names) # [‘Feloriya’, ‘Alexander’]
Python
# Square only even numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
squared_evens = [num ** 2 for num in numbers if num % 2 == 0]
print(squared_evens) # [4, 16, 36, 64, 100]
# Convert Celsius to Fahrenheit for positive temperatures only
celsius = [0, 10, 20, 30, -5, 40, -10]
fahrenheit = [c * 9/5 + 32 for c in celsius if c >= 0]
print(fahrenheit) # [32.0, 50.0, 68.0, 86.0, 104.0]
Python
# Replace even numbers with “even”, odd with “odd”
numbers = [1, 2, 3, 4, 5]
labels = [“even” if num % 2 == 0 else “odd” for num in numbers]
print(labels) # [‘odd’, ‘even’, ‘odd’, ‘even’, ‘odd’]
# Keep sign of number
values = [-3, -2, -1, 0, 1, 2, 3]
sign = [“negative” if x < 0 else “positive” if x > 0 else “zero” for x in values]
print(sign)
Python
# Both filtering and conditional transformation
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
result = [num * 10 if num % 2 == 0 else num for num in numbers if num > 5]
# For numbers > 5: if even -> num*10, if odd -> num
print(result) # [6, 7, 80, 9, 100]
# Explanation: 6>5 and odd -> 6, 7>5 and odd -> 7, 8>5 and even -> 80, etc.
Python
# Flatten a matrix (list of lists)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
print(flat) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Equivalent nested loop
flat = []
for row in matrix:
for num in row:
flat.append(num)
🕯️ Magic Note
The order of for clauses in a nested comprehension follows the order of nesting. The outer loop comes first, then the inner loop. This matches the order you would write in a regular nested loop.
Python
# Create a dictionary: number -> square
squares = {num: num ** 2 for num in range(1, 6)}
print(squares) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Filtered dictionary comprehension
even_squares = {num: num ** 2 for num in range(1, 11) if num % 2 == 0}
print(even_squares) # {2: 4, 4: 16, 6: 36, 8: 64, 10: 100}
# Swap keys and values
original = {“a”: 1, “b”: 2, “c”: 3}
swapped = {value: key for key, value in original.items()}
print(swapped) # {1: ‘a’, 2: ‘b’, 3: ‘c’}
Python
# Set of unique squares
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
unique_squares = {num ** 2 for num in numbers}
print(unique_squares) # {16, 1, 4, 9}
# Set of first letters
words = [“apple”, “banana”, “cherry”, “apricot”, “blueberry”]
first_letters = {word[0] for word in words}
print(first_letters) # {‘c’, ‘b’, ‘a’}
Python
# List comprehension (stores all in memory)
squares_list = [x ** 2 for x in range(1000000)] # Uses lots of memory
# Generator expression (produces one at a time)
squares_gen = (x ** 2 for x in range(1000000)) # Uses almost no memory
for square in squares_gen: # Iterate one at a time
if square > 100:
break
print(square, end=” “)
# 0 1 4 9 16 25 36 49 64 81 100
Python
# map() applies a function to every item
numbers = [1, 2, 3, 4, 5]
doubled = list(map(lambda x: x * 2, numbers))
print(doubled) # [2, 4, 6, 8, 10]
# filter() keeps items where function returns True
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4]
# Equivalent list comprehensions are clearer
doubled = [x * 2 for x in numbers]
evens = [x for x in numbers if x % 2 == 0]
🕯️ Magic Note
List comprehensions replaced map() and filter() for most use cases because they are more readable and can combine mapping and filtering in one expression. However, map() and filter() return iterators, making them memory efficient like generator expressions.
| Method | Speed | Memory Use | Readability |
|---|---|---|---|
| for loop with append | Medium | High (list) | Very clear |
| List comprehension | Fastest | High (list) | Clear (simple cases) |
| Generator expression | Fast | Low (generator) | Clear |
| map() with lambda | Medium | Low (iterator) | Less readable |
Python
# 1. Extract a column from a list of dictionaries
users = [{“name”: “Ali”, “age”: 25}, {“name”: “Sara”, “age”: 30}]
names = [user[“name”] for user in users]
print(names) # [‘Ali’, ‘Sara’]
# 2. Convert strings to integers
str_nums = [“1”, “2”, “3”, “4”, “5”]
int_nums = [int(s) for s in str_nums]
# 3. Remove None values
data = [1, None, 2, None, 3, 4, None, 5]
clean = [x for x in data if x is not None]
print(clean) # [1, 2, 3, 4, 5]
# 4. Flatten a list of lists
nested = [[1, 2], [3, 4], [5, 6]]
flat = [item for sublist in nested for item in sublist]
# 5. Apply multiple transformations
temps = [10, 20, 30, 40]
result = [f”{c}C = {c*9/5+32:.1f}F” for c in temps]
print(result)
- Confusing filter if (after for) with conditional expression if-else (before for)
- Using a list comprehension for side effects (like printing)
- Creating huge lists with comprehensions when a generator would be better
- Making nested comprehensions too complex (more than 2 levels)
- Forgetting that set comprehensions remove duplicates automatically
- Using map() when a comprehension is clearer
- Write a list comprehension that creates a list of squares for numbers 1 to 10.
- Write a list comprehension that filters a list of numbers to only keep those greater than 5.
- Write a list comprehension that doubles only the even numbers from a list.
- How do you create a dictionary comprehension that maps each number to its cube?
- What is the difference between a list comprehension and a generator expression?
- When should you use a regular for loop instead of a comprehension?
⚡ Whisper
Building new lists is the art of transformation. You take raw material, you shape it, you filter out what does not belong, and you create something new. The loop with .append() is like carving by hand, slow and careful, but always reliable. The list comprehension is like a spell, quick and elegant, but demanding precision. The generator is like a stream, giving you water one sip at a time, never flooding your memory. Each tool has its place. Choose the loop when clarity is everything. Choose the comprehension when the transformation is pure and simple. Choose the generator when the river is wide and your cup is small. Learn all three. They will serve you well.