Free demoJob-oriented courses at Debugshala, Old Palasia, Indore. Freshers, non-IT and year-gap welcome.Book a free demo +91-8982385539

Python Sets: Union, Intersection, Difference and Fast Lookups

Lesson 20 of 52 · 9 min · Updated 13 Nov 2026

Learn Python sets with sales examples: removing duplicates, add and discard, union, intersection and difference, fast membership tests and frozenset.

Imagine you run a sweet shop with two branches, one in Sarafa and one in Vijay Nagar. Each branch keeps a list of loyalty-card numbers for customers who bought something in November. The owner asks three questions: how many different customers did we serve, who shopped at both branches, and who visited Sarafa but never came to Vijay Nagar?

With plain lists you would write nested loops and keep checking "have I seen this one already?". It works for 20 customers and becomes slow and error-prone for 20,000.

Each branch's list of card numbers is a perfect fit for a set. "Different customers" is the size of the combined set, "both branches" is an intersection, and "Sarafa only" is a difference. Python answers each question in one short expression.

A Python set is a mutable, unordered collection of unique hashable objects that supports fast membership tests and mathematical operations such as union, intersection and difference.

Sets come right after lists and tuples in this series. Where those two keep every item in order, a set keeps each value once and forgets the order.

What is a set in Python and how do you create one?

You create a set with curly braces around comma-separated values, or by passing any iterable, such as a list or a string, to set(). Duplicates disappear the moment the set is built.

Python
sarafa = {"C101", "C102", "C103", "C101", "C104"}   # C101 typed twice
print(sorted(sarafa), len(sarafa))

bills = ["Ravi", "Neha", "Ravi", "Asha", "Neha", "Ravi"]
customers = set(bills)
print("Bills:", len(bills), "| Unique customers:", len(customers))

print(set("indore"))        # characters, duplicates removed
empty = set()               # NOT {} - that is an empty dict
print(type(empty), type({}))

Two details catch beginners. First, {} creates an empty dictionary, not an empty set, so you must write set(). Second, sets have no fixed order, so printing one may show items in any sequence. In the examples here we wrap sets in sorted() so the output is easy to read.

What can go inside a set?

Only hashable items: numbers, strings, booleans, None and tuples of hashable values. Lists, dictionaries and other sets cannot be members because their contents can change. Trying {[1, 2]} raises TypeError: unhashable type: 'list'.

That limit is the price of speed. The next section explains why.

Quick check

What does x = {} create?

Why are set lookups so fast?

When you ask "C103" in my_list, Python checks each item from the start until it finds a match. With 1 lakh items that can mean 1 lakh comparisons. A set works differently.

How a Python set uses hashing to find an item in one step instead of scanning a list

A list is scanned item by item; a set hashes the value and jumps straight to the slot where it would live.

Python runs each value through a hash function, which turns it into a number. That number points to a slot in an internal table. To check membership, Python hashes the value again and looks only in that slot. The time taken stays roughly the same whether the set holds 10 items or 10 million.

Python
blocked_cards = {"C220", "C315", "C901", "C477"}
todays_bills = [("C101", 450), ("C315", 1200), ("C220", 300), ("C150", 780)]

for card, amount in todays_bills:
    if card in blocked_cards:          # one hash lookup per bill
        print(f"{card}: Rs {amount} - card blocked, ask for cash")
    else:
        print(f"{card}: Rs {amount} - ok")

Whenever you have a "lookup list" that you check again and again, such as blocked IDs, valid PIN codes or SKUs already processed, store it as a set. The loop itself is ordinary; see the for loop tutorial if it is new to you.

How do you add and remove items from a set?

Sets are mutable, so you can grow and shrink them after creation. There is no indexing, though: my_set[0] is an error, because there is no "first" position.

Method What it does If the item is missing
add(x) Add one item Not applicable; adding an existing item does nothing
update(iterable) Add every item from a list, tuple or set Not applicable
remove(x) Delete x Raises KeyError
discard(x) Delete x Does nothing, silently
pop() Remove and return an arbitrary item Raises KeyError if the set is empty
clear() Remove everything Not applicable
Python
regions = {"Indore", "Bhopal"}
regions.add("Ujjain")
regions.add("Indore")                    # already there: no change
regions.update(["Dewas", "Ratlam"])
print(sorted(regions))

regions.discard("Jabalpur")              # missing, but no error
regions.remove("Ratlam")
print(sorted(regions))

try:
    regions.remove("Gwalior")
except KeyError as err:
    print("remove() failed for", err)

Use remove() when a missing item means something is wrong and you want to know. Use discard() when "already gone" is fine.

Set operations: union, intersection and difference

This is where sets earn their place in analytics work. Back at the sweet shop, here are the four questions you can ask of two branch sets.

Venn diagram of Python set union, intersection, difference and symmetric difference on two branch customer sets

Each operation picks a different region of the two overlapping circles.

Question Operator Method Result
Customers at either branch a | b a.union(b) Union
Customers at both branches a & b a.intersection(b) Intersection
At Sarafa but not Vijay Nagar a - b a.difference(b) Difference
At exactly one branch a ^ b a.symmetric_difference(b) Symmetric difference
Python
sarafa = {"C101", "C102", "C103", "C104", "C105"}
vijay_nagar = {"C104", "C105", "C106", "C107"}

print("Either branch :", sorted(sarafa | vijay_nagar))
print("Both branches :", sorted(sarafa & vijay_nagar))
print("Sarafa only   :", sorted(sarafa - vijay_nagar))
print("One branch    :", sorted(sarafa ^ vijay_nagar))

total = len(sarafa | vijay_nagar)
repeat = len(sarafa & vijay_nagar)
print(f"{repeat} of {total} customers ({repeat / total:.0%}) used both branches")

The operators need both sides to be sets. The method forms are more forgiving and accept any iterable, so sarafa.union(["C200", "C201"]) works while sarafa | ["C200"] raises a TypeError.

Updating a set in place

Each operation also has an in-place version that changes the left-hand set instead of building a new one: |=, &=, -= and ^=. A common use is to keep a running set of "IDs already processed" as files arrive.

Python
seen = set()
daily_files = [["C1", "C2", "C3"], ["C2", "C4"], ["C4", "C5", "C1"]]

for day, ids in enumerate(daily_files, start=1):
    new_ids = set(ids) - seen
    seen |= new_ids
    print(f"Day {day}: {len(new_ids)} new customers, {len(seen)} so far")

Quick check

a = {1, 2, 3, 4} and b = {3, 4, 5}. What is a - b?

Subsets, supersets and disjoint sets

Sometimes you need a yes-or-no answer about two groups. Is every product in this order from the approved catalogue? Do these two campaigns share any customers?

  • a <= b or a.issubset(b): every item of a is also in b.
  • a >= b or a.issuperset(b): a contains every item of b.
  • a.isdisjoint(b): the two sets have no items in common.
Python
catalogue = {"kaju-katli", "rasgulla", "namkeen", "gulab-jamun"}
order1 = {"rasgulla", "namkeen"}
order2 = {"rasgulla", "pizza"}

print("Order 1 valid:", order1 <= catalogue)
print("Order 2 valid:", order2 <= catalogue, "| unknown:", order2 - catalogue)

diwali = {"C1", "C2", "C3"}
holi = {"C7", "C8"}
print("Campaigns overlap?", not diwali.isdisjoint(holi))

Notice how order2 - catalogue immediately tells you which item failed the check. Pairing a yes-or-no test with a difference is a handy pattern for data validation.

What is a frozenset in Python?

A frozenset is an immutable set. It supports every operation that reads a set (in, |, &, -, len) but has no add, remove or update. Because it cannot change, it is hashable, so it can be a dictionary key or live inside another set.

Python
combo_sales = {
    frozenset({"samosa", "chai"}): 182,
    frozenset({"poha", "jalebi"}): 240,
}
basket = frozenset({"chai", "samosa"})     # order typed differently
print("Combo sold:", combo_sales[basket])

bundles = {frozenset({"a", "b"}), frozenset({"b", "a"})}
print("Distinct bundles:", len(bundles))

This is useful for market-basket work, where "samosa and chai" is the same combo as "chai and samosa". A tuple would treat those as two different keys.

Common mistakes with Python sets

  • Writing {} for an empty set. That creates a dictionary. Use set().
  • Expecting order. Sets do not keep insertion order, and the printed order can differ between runs. Use sorted(s) when you need a stable display, or list(dict.fromkeys(items)) to remove duplicates while keeping order.
  • Indexing a set. s[0] raises TypeError. Convert to a list or sorted list first.
  • Putting lists inside a set. Lists are unhashable. Convert each one to a tuple.
  • Calling set("Indore") to make a one-item set. It splits the string into characters. Write {"Indore"} instead.
  • Forgetting that "Rahul" and "rahul " are different values. Clean text with strip() and lower() before building the set, or your "unique" count will be too high.

Key takeaways

  • A set stores each hashable value once and has no order or indexes.
  • set(items) removes duplicates; len(set(items)) counts distinct values.
  • in on a set is a hash lookup, so use sets for any list you search repeatedly.
  • |, &, - and ^ answer "either", "both", "only this one" and "exactly one" questions.
  • discard() is silent when the item is missing; remove() raises KeyError.
  • A frozenset is an immutable set that can be used as a dictionary key.

Next in the series is Python dictionaries, which pair each unique key with a value. They use the same hashing idea you just learned.

Take the free Python Programming quiz10 quick questions with explanations. No sign-up needed, and you can come back to this lesson after.

FAQ

What is the difference between a list and a set in Python?

A list keeps items in order, allows duplicates and supports indexing, while a set has no order, keeps each value once and cannot be indexed. Checking membership with in is much faster on a set. Use a list for sequences and a set for unique values and lookups.

How do I remove duplicates from a list using a set?

Call set(my_list), and wrap it in list() if you need a list back. This is fast but loses the original order. When order matters, use list(dict.fromkeys(my_list)), which keeps the first occurrence of each value in its original position.

Is a Python set ordered?

No. A set does not remember insertion order, and the order you see when printing can change between runs and Python versions. Dictionaries do keep insertion order since Python 3.7, but sets never promised it. Use sorted(my_set) whenever you need predictable output.

Can a set contain a list in Python?

No. Set members must be hashable, and lists are mutable and therefore unhashable, so {[1, 2]} raises a TypeError. Convert the list to a tuple, as in {(1, 2)}, or to a frozenset if the order inside it does not matter.

Where can I learn Python sets and data handling in Indore?

Debugshala runs classroom batches at its Old Palasia campus in Indore, taught in English and Hindi, and accepts IT and non-IT graduates. Debugshala's Python-first data analytics course begins with a free demo class, and you can solve set-based practice questions on Debugshala Test.

From the team behind this site

Go further with the Data Analytics Course at Debugshala

These tutorials are written by Debugshala, a training and placement institute at Old Palasia, Indore. The classroom course adds live mentoring, real projects and interview preparation.

  • Offline classes at Old Palasia, Indore
  • Free demo class before you pay
  • Non-IT, fresher and year-gap friendly
  • Placement assistance

700+ students placed · 200+ hiring partners · 4.9★ Google rating

Python Tuples: Immutable Sequences, Unpacking and Use CasesPython Dictionaries: Keys, Values, get(), Loops and Grouping