You need unique file extensions from a list of filenames. Set comprehension {f.split('.')[-1] for f in files} extracts extensions and automatically removes duplicates. Curly braces, like sets themselves.

Basic set creation

Create a set from a sequence.

basic.py
# Basic Set Comprehension

print("=== Basic Set Comprehension ===\n")

# Traditional approach
squares_set = set()
for x in range(1, 6):
    squares_set.add(x ** 2)
print(f"Loop: {squares_set}")

# Set comprehension
squares_comp = {x ** 2 for x in range(1, 6)}
print(f"Comprehension: {squares_comp}")

print("\n=== List vs Set Comprehension ===")

# Same source, different results
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(f"Source: {numbers}")

# List keeps all (with duplicates)
list_result = [n ** 2 for n in numbers]
print(f"List: {list_result}")

# Set removes duplicates
set_result = {n ** 2 for n in numbers}
print(f"Set: {set_result}")

print("\n=== Syntax Comparison ===")
print("List:  [ expression for item in iterable ]")
print("Set:   { expression for item in iterable }")
print("Dict:  { key: value for item in iterable }")
print()
print("Set uses { } but NO colon!")

print("\n=== Character Sets ===")

word = 
print(f"Word: '{word}'")

# Unique characters
unique_chars = {char for char in word}
print(f"Unique chars: {unique_chars}")
print(f"Count: {len(unique_chars)} unique out of {len(word)} total")
# Basic Set Comprehension

print("=== Basic Set Comprehension ===\n")

# Traditional approach
squares_set = set()
for x in range(1, 6):
    squares_set.add(x ** 2)
print(f"Loop: {squares_set}")

# Set comprehension
squares_comp = {x ** 2 for x in range(1, 6)}
print(f"Comprehension: {squares_comp}")

print("\n=== List vs Set Comprehension ===")

# Same source, different results
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(f"Source: {numbers}")

# List keeps all (with duplicates)
list_result = [n ** 2 for n in numbers]
print(f"List: {list_result}")

# Set removes duplicates
set_result = {n ** 2 for n in numbers}
print(f"Set: {set_result}")

print("\n=== Syntax Comparison ===")
print("List:  [ expression for item in iterable ]")
print("Set:   { expression for item in iterable }")
print("Dict:  { key: value for item in iterable }")
print()
print("Set uses { } but NO colon!")

print("\n=== Character Sets ===")

word = 
print(f"Word: '{word}'")

# Unique characters
unique_chars = {char for char in word}
print(f"Unique chars: {unique_chars}")
print(f"Count: {len(unique_chars)} unique out of {len(word)} total")
# Basic Set Comprehension

print("=== Basic Set Comprehension ===\n")

# Traditional approach
squares_set = set()
for x in range(1, 6):
    squares_set.add(x ** 2)
print(f"Loop: {squares_set}")

# Set comprehension
squares_comp = {x ** 2 for x in range(1, 6)}
print(f"Comprehension: {squares_comp}")

print("\n=== List vs Set Comprehension ===")

# Same source, different results
numbers = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(f"Source: {numbers}")

# List keeps all (with duplicates)
list_result = [n ** 2 for n in numbers]
print(f"List: {list_result}")

# Set removes duplicates
set_result = {n ** 2 for n in numbers}
print(f"Set: {set_result}")

print("\n=== Syntax Comparison ===")
print("List:  [ expression for item in iterable ]")
print("Set:   { expression for item in iterable }")
print("Dict:  { key: value for item in iterable }")
print()
print("Set uses { } but NO colon!")

print("\n=== Character Sets ===")

word = 
print(f"Word: '{word}'")

# Unique characters
unique_chars = {char for char in word}
print(f"Unique chars: {unique_chars}")
print(f"Count: {len(unique_chars)} unique out of {len(word)} total")

{expression for item in iterable} - like list comprehension but with {}.

set comprehension Concise set creation: `{x for x in items}`. Auto-removes duplicates.

Extract unique values

Get unique transformed values from data.

unique_values.py
# Extracting Unique Values

print("=== Unique Words from Text ===\n")

text = "The quick brown fox jumps over the lazy dog the fox"
print(f"Text: '{text}'")

# Unique words (case-insensitive)
words = text.lower().split()
unique_words = {word for word in words}
print(f"All words ({len(words)}): {words}")
print(f"Unique ({len(unique_words)}): {unique_words}")

print("\n=== Unique From Collection ===")

# List of items with duplicates
purchases = ["apple", "banana", "apple", "cherry", "banana", "apple"]
print(f"Purchases: {purchases}")

unique_items = {item for item in purchases}
print(f"Unique items: {unique_items}")
print(f"Bought {len(unique_items)} different items")

print("\n=== Unique Domains from Emails ===")

emails = [
    "alice@gmail.com",
    "bob@yahoo.com", 
    "charlie@gmail.com",
    "diana@company.org",
    "eve@yahoo.com"
]
print(f"Emails: {emails}")

# Extract unique domains
domains = {email.split('@')[1] for email in emails}
print(f"Unique domains: {domains}")

print("\n=== Unique Properties from Objects ===")

students = [
    {"name": "Alice", "major": "CS"},
    {"name": "Bob", "major": "Math"},
    {"name": "Charlie", "major": "CS"},
    {"name": "Diana", "major": "Physics"},
    {"name": "Eve", "major": "CS"},
]

# Unique majors
majors = {s["major"] for s in students}
print(f"Unique majors: {majors}")

print("\n=== Unique First Letters ===")

names = ["Alice", "Bob", "Anna", "Bill", "Charlie", "Amy"]
print(f"Names: {names}")

first_letters = {name[0] for name in names}
print(f"First letters: {first_letters}")

Transformation + deduplication in one step.

Filter with conditions

Include only items that pass a test.

with_conditions.py
# Set Comprehension with Conditions

print("=== Filtering in Set Comprehension ===\n")

numbers = list(range(1, 21))
print(f"Numbers: {numbers}")

# Unique even squares
even_squares = {n ** 2 for n in numbers if n % 2 == 0}
print(f"Even squares: {even_squares}")

# Unique odd numbers under 15
odds_under_15 = {n for n in numbers if n % 2 != 0 and n < 15}
print(f"Odds under 15: {odds_under_15}")

print("\n=== String Filtering ===")

words = ["Apple", "banana", "CHERRY", "date", "ELDERBERRY", "fig"]
print(f"Words: {words}")

# Unique lowercase words (length > 4)
long_unique = {w.lower() for w in words if len(w) > 4}
print(f"Long words (lowercase): {long_unique}")

# Words starting with vowel
vowel_words = {w for w in words if w[0].lower() in 'aeiou'}
print(f"Start with vowel: {vowel_words}")

print("\n=== Filtering with Transformation ===")

text = "Hello World Hello Python World"
words = text.split()
print(f"Words: {words}")

# Unique words that appear multiple times
word_list = text.lower().split()
repeated = {w for w in word_list if word_list.count(w) > 1}
print(f"Repeated words: {repeated}")

print("\n=== Multiple Conditions ===")

data = [
    ("apple", 1.50, 10),
    ("banana", 0.75, 0),
    ("cherry", 3.00, 5),
    ("date", 2.25, 8),
    ("elderberry", 4.50, 0),
]

# Unique expensive fruits (>$2) that are in stock
expensive_available = {
    item[0] for item in data 
    if item[1] > 2.00 and item[2] > 0
}
print(f"Expensive & available: {expensive_available}")

Add if condition to filter: {x for x in items if x > 0}.

Set vs list comprehension

Choose the right tool for the job.

vs_list.py
# Set vs List Comprehension: When to Use Which

print("=== When to Use Set vs List ===\n")

# --- Use SET when you need unique values ---

data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
print(f"Data: {data}")

# Question: What unique values exist?
unique = {x for x in data}
print(f"Unique values: {unique}")

# Question: How many different values?
print(f"Count of unique: {len({x for x in data})}")

print("\n=== When to Use LIST ===")

# --- Use LIST when order matters ---

words = ["the", "quick", "the", "fox", "the"]
print(f"Words: {words}")

# Question: What are all the uppercase versions?
upper_list = [w.upper() for w in words]
print(f"Upper (list): {upper_list}")  # Keeps order and count

upper_set = {w.upper() for w in words}
print(f"Upper (set): {upper_set}")  # Loses order and count

print("\n=== Practical Example: Word Analysis ===")

sentence = "to be or not to be that is the question"
words = sentence.split()
print(f"Sentence: '{sentence}'")
print(f"Word count: {len(words)}")  # Total words

# Unique word count
unique_words = {w for w in words}
print(f"Unique words: {len(unique_words)}")
print(f"Unique set: {unique_words}")

print("\n=== Performance Consideration ===")

# Set membership check is O(1)
# List membership check is O(n)

big_list = list(range(10000))
big_set = set(range(10000))

# These do the same check, but set is faster:
print("Checking if 9999 exists:")
print(f"  In list: {9999 in big_list}")  # O(n) - slow
print(f"  In set: {9999 in big_set}")    # O(1) - fast

print("\n=== Decision Guide ===")
print("""
Use SET when:
  ✓ You need unique values only
  ✓ Order doesn't matter
  ✓ You'll do membership checks (x in set)
  ✓ You need set operations (union, intersection)

Use LIST when:
  ✓ Order matters
  ✓ Duplicates are meaningful
  ✓ You need indexing (list[0])
  ✓ You need to preserve frequency
""")

Use set when you need uniqueness. Use list when order matters.

Combine with set operations

Build sets for intersection, union, etc.

set_operations.py
# Set Comprehension with Set Operations

print("=== Set Operations with Comprehensions ===\n")

# Two lists with some overlap
list_a = [1, 2, 3, 4, 5, 3, 2]
list_b = [4, 5, 6, 7, 8, 5, 6]
print(f"List A: {list_a}")
print(f"List B: {list_b}")

# Create sets from lists
set_a = {x for x in list_a}
set_b = {x for x in list_b}
print(f"Set A: {set_a}")
print(f"Set B: {set_b}")

# Union (all unique elements)
union = set_a | set_b
print(f"Union (A | B): {union}")

# Intersection (common elements)
intersection = set_a & set_b
print(f"Intersection (A & B): {intersection}")

# Difference (in A but not B)
diff_a = set_a - set_b
print(f"Difference (A - B): {diff_a}")

# Symmetric difference (in A or B but not both)
sym_diff = set_a ^ set_b
print(f"Symmetric diff (A ^ B): {sym_diff}")

print("\n=== Practical: Compare Two Groups ===")

# Students in two courses
python_students = {"Alice", "Bob", "Charlie", "Diana"}
java_students = {"Charlie", "Diana", "Eve", "Frank"}
print(f"Python: {python_students}")
print(f"Java: {java_students}")

# Students taking both
both = python_students & java_students
print(f"Taking both: {both}")

# Students taking only Python
only_python = python_students - java_students
print(f"Only Python: {only_python}")

# All students
all_students = python_students | java_students
print(f"All students: {all_students}")

print("\n=== Filtering Then Set Operation ===")

numbers = list(range(1, 21))

# Multiples of 3
mult_3 = {n for n in numbers if n % 3 == 0}
print(f"Multiples of 3: {mult_3}")

# Multiples of 5
mult_5 = {n for n in numbers if n % 5 == 0}
print(f"Multiples of 5: {mult_5}")

# Multiples of both (FizzBuzz!)
mult_both = mult_3 & mult_5
print(f"Multiples of both: {mult_both}")

# Multiples of 3 or 5
mult_either = mult_3 | mult_5
print(f"Multiples of 3 or 5: {mult_either}")

Create sets with comprehension, then use &, |, - operators.

Exercise: practical.py

Real-world set comprehension patterns