1️⃣ List Comprehension

📌 What it is

A concise way to create a list from an iterable.

🔹 Syntax

[expression for item in iterable if condition]

🔹 Basic Example

nums = [1, 2, 3, 4, 5]
squares = [x * x for x in nums] # [1, 4, 9, 16, 25]

Equivalent loop:

squares = [] 
for x in nums:
    squares.append(x * x)

🔹 With Condition

even_numbers = [x for x in range(10) if x % 2 == 0] # [4, 16]

🔹 Nested List Comprehension

matrix = [[1, 2], [3, 4], [5, 6]]
flat = [num for row in matrix for num in row] # [1, 2, 3, 4, 5, 6]

2️⃣ Set Comprehension

📌 What it is

Creates a set using comprehension syntax.
Automatically removes duplicates.

🔹 Syntax

{expression for item in iterable if condition}

🔹 Example

nums = [1, 2, 2, 3, 4, 4, 5]
unique_squares = {x * x for x in nums} # {1, 4, 9, 16, 25}
 
words = ["apple", "banana", "banana", "orange"]
unique_words = {w for w in words if "an" in w} # {'banana', 'orange'}

3️⃣ Dict Comprehension

📌 What it is

Creates a dictionary in a clean and readable way.

🔹 Syntax

{key_expression: value_expression for item in iterable if condition}

🔹 Example: Square Mapping

nums = [1, 2, 3, 4]
square_map = {x: x * x for x in nums} # {1: 1, 2: 4, 3: 9, 4: 16}

🔹 Example: Filter Dictionary

scores = {"a": 80, "b": 45, "c": 90}
passed = {k: v for k, v in scores.items() if v >= 50}

🔹 Swap Keys & Values

original = {"a": 1, "b": 2}
swapped = {v: k for k, v in original.items()} # {1: 'a', 2: 'b'}

4️⃣ Generator Expression

📌 What it is

Like list comprehension but:

  • does NOT store values in memory
  • generates values one-by-one (lazy evaluation)

🔹 Syntax

(expression for item in iterable if condition)

🔹 Example

gen = (x * x for x in range(5))

Consume generator:

for val in gen:
    print(val)

🔹 Memory Difference

list_comp = [x * x for x in range(1_000_000)]
gen_comp = (x * x for x in range(1_000_000))
 
# direcly consume 
sum = sum(gen_comp)