< All Topics

Python Sets & Frozensets

Python Sets

Set is a high-performance data structure derived from mathematical set theory. Unlike Lists (which are sequences), Sets are unordered collections designed for two specific purposes: enforcing uniqueness and performing mathematical comparisons.


1. Core Characteristics

  1. Unordered & Unindexed:
    • Sets do not record element position. You cannot ask for my_set[0].
    • Note: Because they are unordered, the way they print to the screen might change every time you run the program.
  2. Unique Elements Only:
    • Duplicates are strictly forbidden. If you try to add a duplicate, Python silently ignores it.
  3. Mutable Structure:
    • You can add or remove items from the set itself.
  4. Immutable Elements Hashable:
    • Crucial: The set is mutable, but the items inside must be immutable (Hashable).
    • Allowed: int, float, str, tuple, frozenset.
    • Banned: list, dict, set.

The “Boolean Trap” (True == 1)

In Python, the boolean True is actually stored as the integer 1, and False as 0. Since sets demand uniqueness, they treat 1 and True as the exact same key.

# 1 and True are duplicates. 0 and False are duplicates.
my_set = {1, True, 0, False}

print(my_set)
# Output: {0, 1} (Python keeps the one that appeared first)

2. Creating Sets

1. The Curly Bracket Syntax {}

This is the standard way, but it has one major “gotcha.”

# Standard Set
colors = {"red", "green", "blue"}

# THE TRAP: Creating an empty set
empty = {}      # THIS IS A DICTIONARY, NOT A SET!
real_set = set() # This is the correct way to make an empty set.

2. The set() Constructor

Used to convert other collections into a set. This is the fastest way to remove duplicates from a list.

raw_data = [1, 2, 2, 3, 3, 3, 4]
clean_data = set(raw_data)

print(clean_data) # Output: {1, 2, 3, 4}

3. Modifying Sets – CRUD Operations

Adding Items

  • .add(x): Adds a single item.
  • .update(iterable): Adds multiple items from a list, tuple, or another set.
s = {1, 2}
s.add(3)           # {1, 2, 3}
s.update([4, 5])   # {1, 2, 3, 4, 5}

Removing Items

There are four distinct ways to remove items, each with different behavior.

MethodDescriptionBehavior if Item Missing
.remove(x)Removes x.Crashes (KeyError)
.discard(x)Removes x.Does Nothing (Safe)
.pop()Removes & returns an arbitrary item.❌ Crashes if set is empty
.clear()Deletes all items.✅ Safe

Why is .pop() random?

Since sets are unordered, there is no “first” or “last” item. .pop() grabs an item based on memory hashing, which can feel random.


4. Mathematical Set Operations

This is the main reason developers use sets. Instead of writing complex for loops to compare lists, you can use these one-line operations.

1. Union | or .union()

“I want everything from both groups.”

  • Combines sets A and B. Duplicates are removed.
  • Code: A | B

2. Intersection & or .intersection()

“I want only the items present in BOTH groups.”

  • Code: A & B

3. Difference or .difference()

“I want items in A that are NOT in B.”

  • Code: A – B

4. Symmetric Difference ^ or .symmetric_difference()

“I want items that are in A OR B, but NOT in both.” (The opposite of Intersection).

  • Code: A ^ B

Example Scenario:

Imagine you have two email lists:

subscribers = {"bob@mail.com", "amy@mail.com", "tom@mail.com"}
unsubscribed = {"tom@mail.com", "tim@mail.com"}

# Send emails to active subscribers only (Subscribers minus Unsubscribed)
to_send = subscribers - unsubscribed 
print(to_send) # {'bob@mail.com', 'amy@mail.com'}

5. Frozenset – Immutable Set

A frozenset is to a set ot is a read-only version of a set.

  1. Dictionary Keys: You cannot use a regular set as a key in a dictionary because it is mutable. You can use a frozenset.
  2. Sets inside Sets: You cannot store a set inside another set (nested sets). You can store a frozenset inside a regular set.
# Creating a Frozenset
fs = frozenset([1, 2, 3])

# fs.add(4)  # AttributeError (Cannot modify)

# Using as a Dictionary Key
locations = {
    frozenset({10, 20}): "Store A",
    frozenset({30, 40}): "Store B"
}

Operation

You can perform an operation and update the original set in one step.

OperatorMethodDescription
`=`.update()
&=.intersection_update()Keep only common items.
-=.difference_update()Remove items found in another set.
^=.symmetric_difference_update()Keep only items found in one, not both.
A = {1, 2, 3}
B = {3, 4}

A -= B  # Remove items in B from A
print(A) # {1, 2}

Summary Table: Set vs List vs Frozenset

FeatureList []Set {}Frozenset ()
Ordered✅ Yes❌ No❌ No
Indexed✅ Yes❌ No❌ No
Mutable✅ Yes✅ Yes❌ No
Duplicates✅ Yes❌ No❌ No
Lookup SpeedSlow ($O(n)$)Fast ($O(1)$)Fast ($O(1)$)
Use CaseData order mattersUniqueness / MathDict Keys / Immutable unique data
Contents
Scroll to Top