Sets

Reviewed & published by Brayan K

A set is Python's collection of unique items. Drop duplicates in and they silently disappear; ask "is this here?" and you get an answer almost instantly. Sets are the right tool whenever uniqueness or fast membership matters.

Part of the free Python course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.

They also bring the elegant math of unions, intersections, and differences — perfect for comparing two groups of things.

What You'll Learn in This Lesson

1 Creating a Set

Write a set with curly braces and commas, or build one from any iterable with set(). Duplicates are removed on the spot:

colors = {"red", "green", "blue"}
print(colors)            # {'red', 'green', 'blue'}  (order may vary)

# Duplicates vanish automatically
nums = {1, 2, 2, 3, 3, 3}
print(nums)              # {1, 2, 3}

# Build a set from a list to de-duplicate it
votes = ["yes", "no", "yes", "yes", "no"]
unique_votes = set(votes)
print(unique_votes)      # {'yes', 'no'}

# A set from a string = its unique characters
print(set("mississippi"))  # {'m', 'i', 's', 'p'}

⚡ The Superpower: Instant Membership Tests

The single biggest reason to use a set is speed. Checking x in some_set is roughly constant time no matter how big the set is, while the same check on a list scans every element:

allowed_users = {"alice", "bob", "carol"}

print("alice" in allowed_users)    # True   (instant)
print("dave" in allowed_users)     # False  (instant)
print("dave" not in allowed_users) # True

# Real use: a blocklist checked thousands of times
banned_ips = {"10.0.0.5", "10.0.0.9", "192.168.1.1"}
incoming = "10.0.0.9"
if incoming in banned_ips:
    print(f"Blocked {incoming}")   # Blocked 10.0.0.9

If your program repeatedly asks "have I seen this before?" or "is this in the allowed list?", store the values in a set. For a large collection the difference is the gap between instant and noticeably slow.

2 Adding and Removing Items

Sets are mutable — you can change their contents (even though the elements must be immutable):

tags = {"python", "code"}

tags.add("tutorial")        # add one item
print(tags)                 # {'python', 'code', 'tutorial'}

tags.add("python")          # adding a duplicate does nothing
print(len(tags))            # 3

tags.update(["web", "css"]) # add several at once
print(len(tags))            # 5

tags.remove("css")          # remove — ERROR if missing
tags.discard("nope")        # discard — safe, no error if missing
popped = tags.pop()         # remove & return an arbitrary item
tags.clear()                # empty it completely
print(tags)                 # set()

3 Set Math: Union, Intersection, Difference

This is where sets shine. Comparing two groups of things becomes a single, readable operation:

frontend = {"alice", "bob", "carol"}
backend  = {"bob", "carol", "dave"}

# Union — everyone in either team (| or .union())
print(frontend | backend)          # {'alice', 'bob', 'carol', 'dave'}

# Intersection — people on BOTH teams (& or .intersection())
print(frontend & backend)          # {'bob', 'carol'}

# Difference — frontend-only people (- or .difference())
print(frontend - backend)          # {'alice'}

# Symmetric difference — in exactly one team (^)
print(frontend ^ backend)          # {'alice', 'dave'}
# Compare two readers' book lists
ada_books = {"Dune", "1984", "Hobbit", "Sapiens"}
ben_books = {"1984", "Sapiens", "Foundation"}

# Books both have read
both = ada_books & ben_books
print("Both read:", both)

# Recommend Ada's books that Ben hasn't read
for_ben = ada_books - ben_books
print("Suggest to Ben:", for_ben)

# The complete combined library
library = ada_books | ben_books
print("Total unique books:", len(library))

# Expected output:
# Both read: {'1984', 'Sapiens'}
# Suggest to Ben: {'Dune', 'Hobbit'}
# Total unique books: 5

🧰 The Classic De-duplication Pattern

One of the most common real uses of a set is to remove duplicates from a list in a single line:

emails = [
    "a@x.com", "b@x.com", "a@x.com", "c@x.com", "b@x.com"
]

# Remove duplicates (order NOT preserved)
unique = list(set(emails))
print(len(unique))          # 3

# Keep first-seen ORDER while de-duplicating (Python 3.7+)
seen = set()
ordered_unique = []
for e in emails:
    if e not in seen:
        seen.add(e)
        ordered_unique.append(e)
print(ordered_unique)       # ['a@x.com', 'b@x.com', 'c@x.com']

list(set(items)) is the quick way, but it scrambles order. The "seen" pattern is the standard idiom when you need uniqueness and the original ordering.

🧩 Reorder Challenge

These lines should find how many tags two articles share. Reorder them so the final output is Shared tags: 2.

A)   shared = a & b
B)   a = {"python", "web", "api"}
C)   print(f"Shared tags: {len(shared)}")
D)   b = {"web", "api", "css"}

B → D → A → C

a = {"python", "web", "api"}      # B
b = {"web", "api", "css"}         # D
shared = a & b                    # A -> {'web', 'api'}
print(f"Shared tags: {len(shared)}")  # C -> Shared tags: 2

Why: both sets a (B) and b (D) must exist before the intersection a & b (A) can run. The print (C) reports the size of that result. The two common tags are web and api.

🧠 Quick Recall

print(len({1, 2, 2, 3, 3, 3}))

3 — sets discard duplicates, leaving only {1, 2, 3}, which has length 3.

2. What is the result?

print({1, 2, 3} & {2, 3, 4})

{2, 3} — the & operator returns the intersection: only the elements present in both sets.

3. What is type(x)?

x = {}
print(type(x))

<class 'dict'> — empty curly braces make a dictionary, not a set. Use set() for an empty set.

📋 Set Operations Cheat Sheet

OperationMeaningExample
x in sMembership (fast)2 in {1,2} → True
s.add(x)Insert one items.add(5)
a | bUnionAll items from both
a & bIntersectionItems in both
a - bDifferenceIn a, not in b
list(set(x))De-duplicateDrop repeats

🎯 Mini Challenge: Find Common Friends

Given two people's friend lists, find mutual friends and friend suggestions.

# 🎯 YOUR TURN: social network logic with sets
maya_friends = {"sam", "leo", "nina", "kai"}
omar_friends = {"leo", "kai", "tess", "zoe"}

# Mutual friends
mutual = maya_friends & omar_friends
print("Mutual friends:", mutual)

# Suggest Omar's friends that Maya doesn't know yet
suggestions = omar_friends - maya_friends
print("Suggest to Maya:", suggestions)

# Everyone in the combined circle
everyone = maya_friends | omar_friends
print("Total people:", len(everyone))

Lesson complete — sets are in your toolkit!

You can create sets, de-duplicate data, run instant membership tests, add and remove items, and use union, intersection, and difference to compare groups. Remember: set() for empty, not {}.

Practice quiz

What is the defining feature of a Python set?

  • It keeps items sorted
  • It allows duplicates
  • It stores only unique items
  • It is indexed by position

Answer: It stores only unique items. A set is an unordered collection that automatically removes duplicates.

What does len({1, 2, 2, 3, 3, 3}) return?

  • 3
  • 6
  • 1
  • 2

Answer: 3. Duplicates are discarded, leaving {1, 2, 3}, which has length 3.

How do you create an EMPTY set?

  • {}
  • []
  • ()
  • set()

Answer: set(). {} creates an empty dict; use set() for an empty set.

What does {1, 2, 3} & {2, 3, 4} produce?

  • {1, 2, 3, 4}
  • {2, 3}
  • {1, 4}
  • {1}

Answer: {2, 3}. The & operator is intersection: only items in both sets, {2, 3}.

Which operator gives the UNION of two sets?

  • |
  • &
  • -
  • ^

Answer: |. The | operator returns the union — all items from both sets.

What does a - b compute for two sets?

  • Items in both
  • Items in either
  • Items in a but not b
  • Items in neither

Answer: Items in a but not b. The - operator is the difference: items in a that aren't in b.

Why is 'x in my_set' faster than 'x in my_list' for large data?

  • Sets are sorted
  • Sets use a hash table (O(1) lookup)
  • Lists are immutable
  • Sets are smaller

Answer: Sets use a hash table (O(1) lookup). Sets are hash-table backed, giving roughly O(1) membership tests vs O(n) for lists.

What's the difference between remove() and discard()?

  • No difference
  • discard() raises KeyError, remove() does not
  • remove() adds items
  • remove() raises KeyError if missing, discard() does not

Answer: remove() raises KeyError if missing, discard() does not. remove() raises a KeyError when the item is absent; discard() is silent.

What is type({}) in Python?

  • set
  • dict
  • list
  • tuple

Answer: dict. Empty curly braces create a dictionary, not a set.

Which one-liner removes duplicates from a list called items?

  • sorted(items)
  • items.unique()
  • list(set(items))
  • set.remove(items)

Answer: list(set(items)). list(set(items)) dedupes by converting to a set and back (order not preserved).

Continue this course

Frequently asked questions

What is a set and how is it different from a list?

A set is an unordered collection that automatically removes duplicates. Unlike a list, you can't index into a set (there's no s[0]) and the order isn't guaranteed. In exchange you get instant membership tests and built-in math operations like union and intersection.

Why is 'x in my_set' so much faster than 'x in my_list'?

Sets are backed by a hash table. Checking membership is roughly O(1) — Python jumps straight to where the value would live. A list has to scan element by element, which is O(n). For large collections of unique values you want to check repeatedly, a set is dramatically faster.

How do I create an empty set?

Use set(), not {}. Writing {} creates an empty dictionary because Python reserved that syntax for dicts first. So empty_set = set() and empty_dict = {}. Once a set has items you can write {1, 2, 3}.

Can a set contain a list or another set?

No — set elements must be hashable (immutable). Numbers, strings, and tuples work; lists, dicts, and other sets do not and raise a TypeError. If you need a set of sets, use frozenset, the immutable cousin of set, as the inner elements.

When should I reach for a set instead of a list?

Use a set when you care about uniqueness, need fast membership checks, or want set algebra (which users are in both groups? which tags are new?). Use a list when order matters, you need duplicates, or you index by position. Converting list(set(items)) is the classic one-liner to dedupe.