Python Sets
Python Sets
A set is a built-in collection used to store multiple values in a single variable — with one important rule: every value in a set is unique. Sets are designed for two things that lists do poorly:
- Removing duplicates from a collection
- Comparing collections — finding common items, differences, and combinations
Sets are one of Python's four built-in collection types, along with lists, tuples, and dictionaries, each designed for different use cases.
What Is a Set?
A set is a collection that is:
- Unordered — items have no fixed position.
- Unindexed — items cannot be accessed by an index such as
[0]. - Unchangeable items — an individual item cannot be modified in place.
- Unique — duplicate values are not allowed.
Note: Although the items themselves cannot be changed, the set is mutable: you can add new items and remove existing ones.
Python's Collection Types Compared
| Collection | Ordered | Changeable | Duplicates | Indexed |
|---|---|---|---|---|
| List | Yes | Yes | Allowed | Yes |
| Tuple | Yes | No | Allowed | Yes |
| Set | No | Add/remove only | Not allowed | No |
| Dictionary | Yes (Python 3.7+) | Yes | No duplicate keys | By key |
Creating a Set
Sets are written with curly braces { }.
fruits_set = {"mango", "orange", "grapes"}
print(fruits_set)
Example output (the order may vary):
{'grapes', 'mango', 'orange'}
Creating an Empty Set
Empty curly braces create an empty dictionary, not a set. Use set() instead:
empty_dict = {}
empty_set = set()
print(type(empty_dict))
print(type(empty_set))
Expected output:
<class 'dict'>
<class 'set'>
Characteristics of Set Items
1. Unordered
Items in a set do not follow a specific order and cannot be accessed by index.
colors = {"red", "blue", "green"}
print(colors)
Example output:
{'blue', 'green', 'red'}
The order you see may differ from the order you wrote, and it may differ between program runs. Never write code that depends on the order of a set.
Because there is no order, indexing fails:
colors = {"red", "blue", "green"}
print(colors[0])
Output:
TypeError: 'set' object is not subscriptable
2. Items Cannot Be Changed, but the Set Can Grow and Shrink
You cannot replace an item directly, but you can add and remove items.
numbers = {1, 2, 3}
numbers.add(4)
numbers.remove(2)
print(numbers)
Expected output:
{1, 3, 4}
To "change" an item, remove the old value and add the new one.
3. No Duplicate Values
Sets automatically discard duplicate values.
cities = {"Delhi", "Mumbai", "Delhi", "Chennai"}
print(cities)
Example output:
{'Chennai', 'Delhi', 'Mumbai'}
"Delhi" was written twice but is stored only once.
Practical Use: Removing Duplicates From a List
emails = ["a@x.com", "b@x.com", "a@x.com", "c@x.com", "b@x.com"]
unique_emails = set(emails)
print(len(emails))
print(len(unique_emails))
Expected output:
5
3
Special Case: Booleans and Integers
In Python, True is equal to 1 and False is equal to 0. A set treats equal values as duplicates, so they cannot both appear:
sample_set = {"python", True, 1, 0, False}
print(sample_set)
Example output:
{0, True, 'python'}
True and 1 count as the same value, as do False and 0. The set keeps the first one it received from each pair.
Set Items Must Be Hashable
Only immutable (more precisely, hashable) values can be stored in a set: numbers, strings, tuples, and frozensets. Lists, dictionaries, and other sets cannot be set items:
data = {[1, 2], [3, 4]}
Output:
TypeError: unhashable type: 'list'
This requirement is what allows sets to check membership extremely quickly.
Finding the Length of a Set
languages = {"Python", "Java", "C++"}
print(len(languages))
Expected output:
3
Set Items and Data Types
Set items can be of any hashable data type.
numbers = {10, 20, 30, 40}
flags = {True, False}
names = {"Alice", "Bob", "Charlie"}
A set can also contain mixed data types:
mixed_set = {"admin", 101, True, 75.5}
print(mixed_set)
Example output:
{True, 'admin', 75.5, 101}
Checking the Data Type of a Set
items = {"pen", "book", "notebook"}
print(type(items))
Expected output:
<class 'set'>
Using the set() Constructor
The set() constructor creates a set from any iterable.
animals = set(("cat", "dog", "rabbit"))
print(animals)
Example output:
{'dog', 'rabbit', 'cat'}
The inner parentheses create a tuple, which set() converts into a set.
Accessing Set Items
Sets have no indexes or keys, so you cannot retrieve a specific item by position. Instead, you work with set items in two ways:
- Looping through the set
- Checking membership with
in
Looping Through a Set
items = {"pen", "pencil", "eraser"}
for element in items:
print(element)
Example output (order may vary):
pencil
eraser
pen
Checking Whether an Item Exists
fruits = {"apple", "banana", "cherry"}
print("banana" in fruits)
Expected output:
True
Checking Whether an Item Does NOT Exist
fruits = {"apple", "banana", "cherry"}
print("orange" not in fruits)
Expected output:
True
Performance note: Membership checks (
in) are much faster on sets than on lists, especially for large collections. A list must be searched item by item; a set uses hashing to find the answer almost immediately. This makes sets ideal for lookups such as "has this user ID already been processed?"
Adding Items to a Set
Adding a Single Item With add()
fruits = {"apple", "banana", "cherry"}
fruits.add("orange")
print(fruits)
Example output:
{'orange', 'banana', 'cherry', 'apple'}
Adding a value that already exists does nothing — no error is raised.
Adding Items From Another Set With update()
fruits = {"apple", "banana", "cherry"}
tropical_fruits = {"mango", "papaya", "pineapple"}
fruits.update(tropical_fruits)
print(fruits)
Example output:
{'papaya', 'apple', 'mango', 'cherry', 'pineapple', 'banana'}
All unique items from tropical_fruits are added to fruits.
Adding Items From Any Iterable
update() accepts any iterable — lists, tuples, dictionaries (their keys are added), and strings.
fruits = {"apple", "banana", "cherry"}
more_fruits = ["kiwi", "orange"]
fruits.update(more_fruits)
print(fruits)
Example output:
{'kiwi', 'banana', 'orange', 'cherry', 'apple'}
Key points:
- Use
add()to insert one item. - Use
update()to insert multiple items. update()works with sets, lists, tuples, and other iterables.- Duplicate values are ignored automatically.
Caution:
update("kiwi")adds the characters'k','i', and'w', because a string is an iterable of characters. Useadd("kiwi")to add the word.
Removing Items From a Set
The method you choose depends on whether the item might be missing and whether you need the removed value.
1. Using remove()
fruits = {"apple", "banana", "cherry"}
fruits.remove("banana")
print(fruits)
Example output:
{'apple', 'cherry'}
Important: If the item does not exist,
remove()raises aKeyError.
fruits.remove("orange")
Output:
KeyError: 'orange'
2. Using discard() (Safer Option)
discard() also removes an item, but does not raise an error if the item is missing.
fruits = {"apple", "banana", "cherry"}
fruits.discard("banana")
fruits.discard("orange") # No error, even though 'orange' is missing
print(fruits)
Example output:
{'apple', 'cherry'}
3. Using pop() (Arbitrary Removal)
pop() removes and returns an arbitrary item. Because sets are unordered, you cannot choose or predict which item is removed.
fruits = {"apple", "banana", "cherry"}
removed_item = fruits.pop()
print("Removed:", removed_item)
print("Remaining:", fruits)
Example output:
Removed: cherry
Remaining: {'apple', 'banana'}
Calling pop() on an empty set raises a KeyError.
4. Using clear() (Empty the Set)
fruits = {"apple", "banana", "cherry"}
fruits.clear()
print(fruits)
Expected output:
set()
An empty set is displayed as set(), because {} represents an empty dictionary.
5. Using del (Delete the Set Completely)
fruits = {"apple", "banana", "cherry"}
del fruits
After this, the name fruits no longer exists; using it raises a NameError.
| Tool | Behavior When the Item Is Missing | Returns the Removed Item |
|---|---|---|
remove(item) | Raises KeyError | No |
discard(item) | Does nothing | No |
pop() | Raises KeyError if the set is empty | Yes (an arbitrary item) |
clear() | — | No |
Looping Through a Set
Because sets have no indexes, a for loop is the way to read every item.
colors = {"red", "blue", "green"}
for color in colors:
print(f"Color available: {color}")
Example output:
Color available: green
Color available: red
Color available: blue
If you need a predictable order, loop over sorted(colors) instead.
Key points:
- Sets do not support indexing.
- Use a
forloop to access items. - The output order is not guaranteed.
- Sets are ideal for working with unique values.
Joining and Comparing Sets
Sets support mathematical set operations that combine or compare collections. These operations answer questions such as Which items are in either group? Which are in both? Which are only in one?
| Method | Operator | Returns | |
|---|---|---|---|
union() | ` | ` | All unique items from both sets |
intersection() | & | Only items found in both sets | |
difference() | - | Items in the first set but not the second | |
symmetric_difference() | ^ | Items in either set, but not both |
Each of these returns a new set. Each also has an _update() version that modifies the original set instead.
Throughout this section, remember that the printed order of set items may vary.
Union — Combine All Items
union() returns a new set containing every unique item from both sets.
group_a = {"red", "blue", "green"}
group_b = {10, 20, 30}
result = group_a.union(group_b)
print(result)
Example output:
{'blue', 10, 'green', 20, 'red', 30}
Using the | Operator
result = group_a | group_b
print(result)
This produces the same set.
Joining Multiple Sets
set_a = {"x", "y"}
set_b = {1, 2}
set_c = {"Alice", "Bob"}
set_d = {"car", "bike"}
combined = set_a.union(set_b, set_c, set_d)
print(combined)
Example output:
{1, 2, 'x', 'Bob', 'car', 'y', 'Alice', 'bike'}
The operator version chains multiple | operators:
combined = set_a | set_b | set_c | set_d
Joining a Set With Other Iterables
union() accepts any iterable, such as a list or tuple:
letters = {"a", "b", "c"}
numbers = (4, 5, 6)
merged = letters.union(numbers)
print(merged)
Example output:
{4, 5, 6, 'a', 'b', 'c'}
The | operator, however, works only between sets:
letters | (4, 5, 6)
Output:
TypeError: unsupported operand type(s) for |: 'set' and 'tuple'
Update — Modify the Original Set
update() adds items from another set or iterable directly into the original set.
base_set = {"pen", "pencil"}
extra_items = {"eraser", "marker"}
base_set.update(extra_items)
print(base_set)
Example output:
{'marker', 'pen', 'eraser', 'pencil'}
Unlike union(), update() returns None; it changes base_set itself. The operator form is |=.
Intersection — Keep Only Common Items
intersection() returns items that exist in both sets.
tech_a = {"Python", "Java", "C++"}
tech_b = {"Python", "Go", "Rust"}
common = tech_a.intersection(tech_b)
print(common)
Expected output:
{'Python'}
Using the & Operator
common = tech_a & tech_b
print(common)
Expected output:
{'Python'}
intersection_update() — Modify the Original Set
tech_a = {"Python", "Java", "C++"}
tech_b = {"Python", "Go", "Rust"}
tech_a.intersection_update(tech_b)
print(tech_a)
Expected output:
{'Python'}
Boolean Values in an Intersection
Because True == 1 and False == 0, they match each other in set operations:
set_one = {"apple", 1, True, 0}
set_two = {False, 1, "apple", 2}
common = set_one.intersection(set_two)
print(common)
Example output:
{'apple', 1, 0}
set_one actually contains only "apple", 1, and 0 (True was a duplicate of 1). The intersection matches 1 with 1, and 0 with False.
Difference — Items Only in the First Set
difference() returns items that are in the first set but not in the second.
set_x = {"cat", "dog", "rabbit"}
set_y = {"dog", "horse"}
unique = set_x.difference(set_y)
print(unique)
Example output:
{'cat', 'rabbit'}
"horse" is not included, because difference only returns items from the first set. Order matters: set_y - set_x would be {'horse'}.
Using the - Operator
unique = set_x - set_y
print(unique)
difference_update() — Modify the Original Set
set_x = {"cat", "dog", "rabbit"}
set_y = {"dog", "horse"}
set_x.difference_update(set_y)
print(set_x)
Example output:
{'cat', 'rabbit'}
Symmetric Difference — Items Not Shared
symmetric_difference() returns items that are in either set, but not in both.
team_a = {"Alice", "Bob", "Charlie"}
team_b = {"Bob", "Diana"}
result = team_a.symmetric_difference(team_b)
print(result)
Example output:
{'Alice', 'Charlie', 'Diana'}
"Bob" is excluded because he belongs to both teams.
Using the ^ Operator
result = team_a ^ team_b
print(result)
symmetric_difference_update() — Modify the Original Set
team_a = {"Alice", "Bob", "Charlie"}
team_b = {"Bob", "Diana"}
team_a.symmetric_difference_update(team_b)
print(team_a)
Example output:
{'Alice', 'Charlie', 'Diana'}
Practical Example: Comparing Course Enrollments
python_students = {"Asha", "Ravi", "Meena", "John"}
django_students = {"Ravi", "John", "Priya"}
print("Taking both:", python_students & django_students)
print("Python only:", python_students - django_students)
print("All students:", python_students | django_students)
Example output:
Taking both: {'Ravi', 'John'}
Python only: {'Asha', 'Meena'}
All students: {'Priya', 'Ravi', 'Asha', 'Meena', 'John'}
Summary of set operations:
- Use
union()(|) to combine all unique items. - Use
intersection()(&) to find common items. - Use
difference()(-) to find items only in the first set. - Use
symmetric_difference()(^) to find items that are not shared. - Methods ending in
_update()modify the original set instead of returning a new one.
Frozenset
A frozenset is an immutable version of a set. It behaves like a normal set, but once it is created, items cannot be added or removed.
What Is a Frozenset?
A frozenset is:
- Unordered — no fixed order of items
- Unique — no duplicate values
- Immutable — items cannot be added or removed
The key difference from a normal set is immutability. Because a frozenset cannot change, it is hashable, so it can be used as a dictionary key or stored inside another set — something a normal set cannot do.
Creating a Frozenset
Use the frozenset() constructor with any iterable.
items = frozenset(["pen", "pencil", "eraser"])
print(items)
print(type(items))
Example output:
frozenset({'pencil', 'eraser', 'pen'})
<class 'frozenset'>
Trying to modify it raises an error:
items.add("marker")
Output:
AttributeError: 'frozenset' object has no attribute 'add'
Operations Supported by Frozensets
Frozensets support all set operations that do not modify the set. Each returns a new frozenset.
1. copy() — Create a Copy
fs = frozenset([1, 2, 3])
new_fs = fs.copy()
print(new_fs)
Expected output:
frozenset({1, 2, 3})
2. union() — Combine Items
a = frozenset(["a", "b"])
b = frozenset([1, 2])
result = a.union(b)
print(result)
result = a | b
print(result)
Example output:
frozenset({1, 2, 'a', 'b'})
frozenset({1, 2, 'a', 'b'})
3. intersection() — Common Items
x = frozenset(["apple", "banana", "cherry"])
y = frozenset(["banana", "kiwi"])
common = x.intersection(y)
print(common)
common = x & y
print(common)
Expected output:
frozenset({'banana'})
frozenset({'banana'})
4. difference() — Items Only in the First
x = frozenset([1, 2, 3, 4])
y = frozenset([3, 4])
diff = x.difference(y)
print(diff)
diff = x - y
print(diff)
Expected output:
frozenset({1, 2})
frozenset({1, 2})
5. symmetric_difference() — Items Not Shared
x = frozenset([1, 2, 3])
y = frozenset([3, 4, 5])
result = x.symmetric_difference(y)
print(result)
result = x ^ y
print(result)
Expected output:
frozenset({1, 2, 4, 5})
frozenset({1, 2, 4, 5})
6. Subset and Superset Checks
a = frozenset([1, 2])
b = frozenset([1, 2, 3])
print(a.issubset(b))
print(b.issuperset(a))
print(a <= b)
print(b >= a)
Expected output:
True
True
True
True
ais a subset ofbbecause every item ofais inb.bis a superset ofabecause it contains every item ofa.
7. isdisjoint() — No Common Items
a = frozenset([1, 2])
b = frozenset([3, 4])
print(a.isdisjoint(b))
Expected output:
True
Set Methods Reference
1. add() — Add One Item
items = {"pen", "pencil"}
items.add("eraser")
print(items)
Example output:
{'eraser', 'pen', 'pencil'}
2. clear() — Remove All Items
numbers = {1, 2, 3}
numbers.clear()
print(numbers)
Expected output:
set()
3. copy() — Copy the Set
Returns a shallow copy.
colors = {"red", "green", "blue"}
backup = colors.copy()
print(backup)
Example output:
{'green', 'red', 'blue'}
4. difference() (-) — Items Only in the First Set
a = {"cat", "dog", "rabbit"}
b = {"dog", "horse"}
print(a.difference(b))
print(a - b)
Example output:
{'cat', 'rabbit'}
{'cat', 'rabbit'}
5. difference_update() (-=) — Remove Items Found in Another Set
a = {1, 2, 3, 4}
b = {3, 4}
a.difference_update(b)
print(a)
Expected output:
{1, 2}
6. discard() — Remove an Item Without an Error
fruits = {"apple", "banana", "cherry"}
fruits.discard("banana")
print(fruits)
Example output:
{'apple', 'cherry'}
7. intersection() (&) — Common Items
x = {"Python", "Java", "C++"}
y = {"Python", "Go"}
print(x.intersection(y))
print(x & y)
Expected output:
{'Python'}
{'Python'}
8. intersection_update() (&=) — Keep Only Common Items
x = {10, 20, 30}
y = {20, 40}
x.intersection_update(y)
print(x)
Expected output:
{20}
9. isdisjoint() — Check for No Common Items
a = {1, 2}
b = {3, 4}
print(a.isdisjoint(b))
Expected output:
True
10. issubset() (<=, <) — Subset Check
a = {1, 2}
b = {1, 2, 3}
print(a.issubset(b))
print(a <= b)
print(a < b)
Expected output:
True
True
True
<=checks for a subset (the sets may be equal).<checks for a proper subset —amust be a subset ofband smaller than it.{1, 2} < {1, 2}isFalse.
11. issuperset() (>=, >) — Superset Check
a = {1, 2, 3}
b = {1, 2}
print(a.issuperset(b))
print(a >= b)
print(a > b)
Expected output:
True
True
True
12. pop() — Remove an Arbitrary Item
values = {"a", "b", "c"}
removed = values.pop()
print("Removed:", removed)
print("Remaining:", values)
Example output:
Removed: b
Remaining: {'a', 'c'}
13. remove() — Remove a Specific Item
Raises a KeyError if the item does not exist.
items = {"pen", "pencil"}
items.remove("pen")
print(items)
Expected output:
{'pencil'}
14. symmetric_difference() (^) — Items Not Shared
a = {"red", "blue"}
b = {"blue", "green"}
print(a.symmetric_difference(b))
print(a ^ b)
Example output:
{'red', 'green'}
{'red', 'green'}
15. symmetric_difference_update() (^=) — Keep Only Non-Shared Items
a = {1, 2, 3}
b = {3, 4}
a.symmetric_difference_update(b)
print(a)
Expected output:
{1, 2, 4}
16. union() (|) — Combine Sets
a = {"x", "y"}
b = {1, 2}
print(a.union(b))
print(a | b)
Example output:
{1, 2, 'x', 'y'}
{1, 2, 'x', 'y'}
17. update() (|=) — Add Items From Another Set or Iterable
a = {"pen", "pencil"}
b = {"eraser", "marker"}
a.update(b)
print(a)
Example output:
{'pencil', 'marker', 'eraser', 'pen'}
Summary Table
| Method | Operator | Purpose | Modifies the Original | |
|---|---|---|---|---|
add() | — | Add one item | Yes | |
clear() | — | Remove all items | Yes | |
copy() | — | Return a shallow copy | No | |
difference() | - | Items only in the first set | No | |
difference_update() | -= | Remove items found in another set | Yes | |
discard() | — | Remove an item if present | Yes | |
intersection() | & | Common items | No | |
intersection_update() | &= | Keep only common items | Yes | |
isdisjoint() | — | True if no items are shared | No | |
issubset() | <=, < | Subset check | No | |
issuperset() | >=, > | Superset check | No | |
pop() | — | Remove and return an arbitrary item | Yes | |
remove() | — | Remove an item; error if missing | Yes | |
symmetric_difference() | ^ | Items not shared | No | |
symmetric_difference_update() | ^= | Keep only non-shared items | Yes | |
union() | ` | ` | All items from both sets | No |
update() | ` | =` | Add items from another set or iterable | Yes |
Common Mistakes
| Mistake | Example | Problem |
|---|---|---|
Using {} for an empty set | s = {} | Creates a dictionary; use set() |
| Accessing by index | s[0] | TypeError: sets are not subscriptable |
| Relying on order | Expecting items in insertion order | Set order is not guaranteed |
| Adding a list to a set | s.add([1, 2]) | TypeError: unhashable type: 'list' |
Using update() with a single string | s.update("kiwi") | Adds individual characters |
Using remove() for an item that may be missing | s.remove("x") | KeyError; use discard() |
Related Concepts
- Python Lists — ordered collections that allow duplicates
- Python Tuples — ordered, immutable collections
- Python Dictionaries — key–value collections whose keys behave like a set
- Python Operators — membership operators
inandnot in