- Basic syntax — how set comprehension works
- Conditional filtering — using if to filter elements
- if-else in comprehension — conditional expressions
- Nested comprehension — working with nested loops
- Multiple conditions — combining filters
- Set vs List comprehension — key differences
- Performance — when and why to use set comprehension
- Common mistakes — and how to avoid them
Introduction to Set Comprehension
Set comprehension is a concise and powerful Python feature that allows you to create new sets by applying an expression to each element of an existing iterable. It combines the process of iteration and transformation into a single, readable line of code.
Set comprehensions are often more readable and performant than traditional for loops for set creation. They follow a syntax that closely resembles how you would describe the operation in plain English.
The basic structure of a set comprehension is:
{expression for item in iterable if condition}
Where:
- expression — the operation to perform on each element
- item — the variable representing each element
- iterable — the source collection (list, set, range, etc.)
- if condition — optional filter (only include items that satisfy the condition)
💡 Key concept: Set comprehension automatically removes duplicates because sets only store unique elements. This is one of the key advantages over list comprehension.
Basic Syntax
Transforming Elements
The simplest form of set comprehension applies an expression to each element in the iterable and creates a new set with the results.
# Basic set comprehension
numbers = [1, 2, 3, 4, 5]
# Square each number
squares = {num ** 2 for num in numbers}
print(squares) # {1, 4, 9, 16, 25}
# Convert to strings
str_numbers = {str(num) for num in numbers}
print(str_numbers) # {'1', '2', '3', '4', '5'}
# Apply a function
def double(x):
return x * 2
doubled = {double(num) for num in numbers}
print(doubled) # {2, 4, 6, 8, 10}
# Working with strings
words = ["apple", "banana", "cherry"]
uppercase = {word.upper() for word in words}
print(uppercase) # {'APPLE', 'BANANA', 'CHERRY'}
# Get lengths
lengths = {len(word) for word in words}
print(lengths) # {5, 6}
# Automatic duplicate removal
numbers = [1, 2, 2, 3, 3, 3, 4, 5, 5]
unique = {num for num in numbers}
print(unique) # {1, 2, 3, 4, 5}
Characteristics:
- Creates a new set — original iterable remains unchanged
- Syntax:
{expression for item in iterable} - Can use any expression including function calls
- Works with any iterable (lists, tuples, ranges, etc.)
- Automatic duplicate removal — unique elements only
Quick Check: Does set comprehension allow duplicate elements? (Answer: No — sets store only unique elements)
With Conditional Filtering
Filtering Elements with if
The if clause in a set comprehension allows you to filter elements — only items that satisfy the condition are included in the new set.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Only even numbers
evens = {num for num in numbers if num % 2 == 0}
print(evens) # {2, 4, 6, 8, 10}
# Only numbers greater than 5
greater_than_5 = {num for num in numbers if num > 5}
print(greater_than_5) # {6, 7, 8, 9, 10}
# With strings - words with length > 5
words = ["apple", "banana", "cherry", "date", "elderberry"]
long_words = {word for word in words if len(word) > 5}
print(long_words) # {'banana', 'cherry', 'elderberry'}
# Words starting with a specific letter
a_words = {word for word in words if word.startswith('a')}
print(a_words) # {'apple'}
# Filtering and transforming together
squares_of_evens = {num ** 2 for num in numbers if num % 2 == 0}
print(squares_of_evens) # {4, 16, 36, 64, 100}
# With duplicate values (automatic removal)
numbers = [1, 2, 2, 3, 4, 4, 5, 6, 6]
even_evens = {num for num in numbers if num % 2 == 0}
print(even_evens) # {2, 4, 6}
Characteristics:
- Syntax:
{expression for item in iterable if condition} - Only items that satisfy the condition are included
- Can be combined with transformation in the same line
- Equivalent to:
for item in iterable: if condition: add(expression)
Quick Check: What does the if clause do in set comprehension? (Answer: It filters elements — only those that satisfy the condition are included)
Using if-else in Comprehension
Conditional Expressions
The if-else construct can be used within the expression part of a set comprehension to apply different transformations based on a condition.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Replace even numbers with "even", odd with "odd"
labels = {"even" if num % 2 == 0 else "odd" for num in numbers}
print(labels) # {'odd', 'even'}
# Mark numbers greater than 5 as "high", others as "low"
categories = {"high" if num > 5 else "low" for num in numbers}
print(categories) # {'low', 'high'}
# Square even numbers, leave odd numbers unchanged
processed = {num ** 2 if num % 2 == 0 else num for num in numbers}
print(processed) # {1, 4, 3, 16, 5, 36, 7, 64, 9, 100}
# With strings - convert to uppercase if length > 3, else lowercase
words = ["apple", "banana", "cat", "dog", "elderberry"]
modified = {word.upper() if len(word) > 3 else word.lower() for word in words}
print(modified) # {'APPLE', 'BANANA', 'cat', 'dog', 'ELDERBERRY'}
# Practical example: categorize numbers
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
categories = {"even" if num % 2 == 0 else "odd" for num in numbers}
print(categories) # {'even', 'odd'}
Important distinction:
- if at the end — filters items:
{x for x in list if condition} - if-else in expression — transforms items:
{x if condition else y for x in list} - Both can be used in the same comprehension
# Filter AND transform
result = {num ** 2 if num % 2 == 0 else num for num in numbers if num > 3}
# First filter: num > 3, then transform: square if even, keep if odd
Quick Check: What is the difference between if at the end and if-else in expression? (Answer: if at the end filters; if-else in expression transforms)
Nested Set Comprehension
Working with Nested Loops
Set comprehension can include nested loops, similar to nested for loops. This is useful for flattening data or working with matrices.
# Flatten a matrix (list of lists)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = {num for row in matrix for num in row}
print(flattened) # {1, 2, 3, 4, 5, 6, 7, 8, 9}
# Equivalent nested for loop:
# flattened = set()
# for row in matrix:
# for num in row:
# flattened.add(num)
# Nested comprehension with filtering
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
even_numbers = {num for row in matrix for num in row if num % 2 == 0}
print(even_numbers) # {2, 4, 6, 8}
# Creating a multiplication table (set of products)
products = {i * j for i in range(1, 4) for j in range(1, 4)}
print(products) # {1, 2, 3, 4, 6, 9}
# Flatten with duplicate removal
matrix = [[1, 1, 2], [2, 3, 3], [4, 4, 5]]
unique_flattened = {num for row in matrix for num in row}
print(unique_flattened) # {1, 2, 3, 4, 5}
Characteristics:
- Loop order follows the same order as nested for loops
- Can have multiple levels of nesting
- Useful for flattening and matrix operations
- Readability decreases with too many nested levels
- Automatic duplicate removal applies
Quick Check: What is the order of loops in a nested set comprehension? (Answer: The order matches nested for loops — outer loop first, then inner loop)
Multiple Conditions
Combining Filters
Set comprehension supports multiple conditions using multiple if clauses or logical operators.
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# Multiple if conditions
result = {num for num in numbers if num > 3 if num < 8}
print(result) # {4, 5, 6, 7}
# Using logical operators (and, or)
result = {num for num in numbers if num > 3 and num < 8}
print(result) # {4, 5, 6, 7}
# Numbers that are even OR greater than 7
result = {num for num in numbers if num % 2 == 0 or num > 7}
print(result) # {2, 4, 6, 8, 9, 10}
# With strings - words with length > 3 AND contain 'a'
words = ["apple", "banana", "cat", "dog", "grape", "kiwi"]
result = {word for word in words if len(word) > 3 and 'a' in word}
print(result) # {'apple', 'banana', 'grape'}
Guidelines:
- Multiple
ifclauses act as AND conditions - Use
and,orfor more complex logic - Multiple if clauses are less common than using and/or
- Keep conditions simple for readability
Set vs List Comprehension
Key Differences
Understanding the differences between set and list comprehension helps you choose the right approach for your needs.
# List comprehension (creates a list)
list_comp = [x ** 2 for x in [1, 2, 2, 3, 3, 3, 4]]
print(list_comp) # [1, 4, 4, 9, 9, 9, 16] — duplicates allowed
print(type(list_comp)) # <class 'list'>
# Set comprehension (creates a set)
set_comp = {x ** 2 for x in [1, 2, 2, 3, 3, 3, 4]}
print(set_comp) # {1, 4, 9, 16} — duplicates removed
print(type(set_comp)) # <class 'set'>
# Memory comparison
import sys
list_comp = [x for x in range(1000)]
set_comp = {x for x in range(1000)}
print(f"List size: {sys.getsizeof(list_comp)} bytes")
print(f"Set size: {sys.getsizeof(set_comp)} bytes")
# List: ~8,728 bytes
# Set: ~32,984 bytes (sets use more memory)
Comparison:
- List comprehension — creates a list, allows duplicates
- Set comprehension — creates a set, removes duplicates
- Memory — sets use more memory than lists
- Order — lists maintain order; sets are unordered
- Use set comprehension — when you need unique elements
Quick Check: What is the main difference between set and list comprehension? (Answer: Set comprehension removes duplicates; list comprehension allows duplicates)
Performance Considerations
When to Use Set Comprehension
Set comprehension is generally faster than a for loop with add() because it is implemented in C and optimized for set creation.
import time
# Using for loop with add
numbers = range(1, 1000000)
start = time.time()
squares_loop = set()
for num in numbers:
squares_loop.add(num ** 2)
print(f"Loop time: {time.time() - start:.4f}s")
# Using set comprehension
numbers = range(1, 1000000)
start = time.time()
squares_comp = {num ** 2 for num in numbers}
print(f"Set comprehension time: {time.time() - start:.4f}s")
# Output (approximate):
# Loop time: 0.1450s
# Set comprehension time: 0.0950s
# When NOT to use set comprehension:
# 1. Complex logic
# 2. Side effects (e.g., printing)
# 3. Multiple operations
# 4. When order matters
Performance summary:
- Faster: Set comprehension is usually faster than for loops
- Memory: Creates a complete set in memory
- Use when: Simple transformation or filtering, need unique elements
- Avoid when: Complex logic, side effects, or when order matters
Quick Check: Is set comprehension always the best choice? (Answer: No — avoid it for complex logic, side effects, or when order matters)
Common Mistakes
Pitfalls and Solutions
Confusing Set and List Comprehension
# WRONG — using square brackets creates a list
numbers = [1, 2, 3, 4, 5]
squares = [num ** 2 for num in numbers] # This is a list
# CORRECT — using curly braces creates a set
squares = {num ** 2 for num in numbers} # This is a set
Assuming Set Order
# WRONG — sets are unordered
numbers = [3, 1, 4, 1, 5, 9, 2]
unique = {num for num in numbers}
print(unique) # {1, 2, 3, 4, 5, 9} — order may vary
# CORRECT — use list if order matters
unique_list = list(dict.fromkeys(numbers))
print(unique_list) # [3, 1, 4, 5, 9, 2] — maintains order
Using Unhashable Types
# WRONG — lists are unhashable
# result = {[1, 2] for x in range(3)} # TypeError
# CORRECT — use tuples or other hashable types
result = {(1, 2) for x in range(3)}
print(result) # {(1, 2)}
Overly Complex Comprehensions
# Bad — too complex, hard to read
result = {x ** 2 if x % 2 == 0 else x ** 3 if x % 3 == 0 else x for x in range(1, 20)}
# Better — use a regular loop for complex logic
result = set()
for x in range(1, 20):
if x % 2 == 0:
result.add(x ** 2)
elif x % 3 == 0:
result.add(x ** 3)
else:
result.add(x)
Quick Check: What is the most common mistake with set comprehension? (Answer: Confusing it with list comprehension — using [] instead of {})
Interactive Editor
Experiment with set comprehension in the interactive editor below. Modify the code and observe the results in real time.
SET COMPREHENSION PRACTICE
========================================
Numbers: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Words: ['apple', 'banana', 'cherry', 'date', 'elderberry']
Duplicates: [1, 2, 2, 3, 3, 3, 4, 5, 5]
1. BASIC TRANSFORMATION
Squares: {1, 4, 9, 16, 25, 36, 49, 64, 81, 100}
2. FILTERING
Even numbers: {2, 4, 6, 8, 10}
3. IF-ELSE IN EXPRESSION
Labels: {'even', 'odd'}
4. NESTED COMPREHENSION
Flattened matrix: {1, 2, 3, 4, 5, 6, 7, 8, 9}
5. AUTOMATIC DUPLICATE REMOVAL
Original: [1, 2, 2, 3, 3, 3, 4, 5, 5]
Unique: {1, 2, 3, 4, 5}
6. MULTIPLE CONDITIONS
Numbers between 3 and 8: {4, 5, 6, 7}
7. SET VS LIST COMPREHENSION
List comprehension: [1, 2, 2, 3, 3, 3, 4, 5, 5]
Set comprehension: {1, 2, 3, 4, 5}
Set comprehension practice complete!
Certificate of Completion
You have completed the Python Set Comprehension tutorial. You now understand basic syntax, conditional filtering, if-else in comprehension, nested comprehension, and key differences from list comprehension.
Quick Quiz — Test Your Knowledge
Let's see what you've learned about set comprehension:
Frequently Asked Questions
What is set comprehension in Python?
What is the difference between set and list comprehension?
{} and creates a set (unique elements only). List comprehension uses square brackets [] and creates a list (allows duplicates).
Does set comprehension remove duplicates?
Can I have multiple if conditions in set comprehension?
and/or operators or multiple if clauses. For example: {x for x in list if x > 0 and x < 10}.
Is set comprehension faster than a for loop?
add() because it is implemented in C and optimized for set creation. However, the performance difference is only significant for large datasets.
When should I NOT use set comprehension?
Where to Go From Here
After mastering set comprehension, consider exploring these related topics:
Set Assignments
Practice your set skills with assignments.
Learn More →Dictionary Comprehension
Create dictionaries concisely using comprehension syntax.
Learn More →List vs Set
Understand when to use lists and when to use sets.
Learn More →