Placement Prep

Python Sets Explained: Create, Modify, and Use Set Operations

Python sets store unique elements and check membership in O(1) time. Covers creation, set methods, operations, and placement coding patterns with examples.

By FACE Prep Team 6 min read
python data-structures placement-prep python-sets coding-interview python-tutorial

A Python set stores only unique, unordered elements and checks membership in O(1) time. That makes it the right data structure for deduplication, fast-lookup problems, and set-algebra tasks that appear across placement coding rounds and production codebases.

Why Choose a Set Over a List

Lists allow duplicates and preserve insertion order. Sets allow neither. The practical trade-off:

PropertyListSet
OrderedYesNo
Allows duplicatesYesNo
Membership test speedO(n)O(1) average
Supports indexingYesNo
MutableYesYes

The O(1) membership test comes from the hash table that backs every Python set. When Python evaluates x in my_set, it hashes x and jumps directly to the matching bucket, with no sequential scan required. The same check on a list scans from index 0 until it finds a match or exhausts every element.

That difference has a practical effect. Checking whether a value exists in a set takes roughly the same time regardless of how many items the set contains. A list check grows linearly with the collection size. For any problem that involves repeated membership tests against a large collection, a set is the correct choice.

The flip side: sets are unordered, so you cannot index them, and they do not preserve insertion sequence. Use a list when order matters or when duplicates are meaningful data. Use a set when uniqueness and lookup speed are the deciding factors.

Creating Sets in Python

According to the Python documentation on set types, two creation patterns exist.

Set literals

languages = {"Python", "Java", "C++"}
numbers   = {10, 20, 30, 40}
mixed     = {1, "hello", 3.14}

A set literal uses curly braces with at least one element. Python discards duplicates automatically:

s = {1, 2, 2, 3, 3, 3}
# s → {1, 2, 3}

The set() constructor

from_list   = set([1, 2, 2, 3, 3])   # duplicates dropped → {1, 2, 3}
from_string = set("hello")            # → {'h', 'e', 'l', 'o'}
empty_set   = set()                   # empty set

The set() constructor accepts any iterable. Strings, lists, tuples, and ranges all work. Duplicates across any of them are dropped.

The empty-set trap

empty_dict = {}    # This is a dictionary, not a set
empty_set  = set() # This is a set

{} with no elements creates an empty dictionary. set() with no arguments creates an empty set. This confusion appears regularly in multiple-choice questions at online tests for IT services companies, so it is worth committing to memory.

Frozenset: the immutable variant

A frozenset is an immutable version of a set. It supports all the read-only operations (membership testing, union, intersection, difference) but cannot be modified after creation.

fs = frozenset([1, 2, 3])
# fs.add(4)  → AttributeError: 'frozenset' object has no attribute 'add'

Because frozenset is immutable it is also hashable, which means it can serve as a dictionary key or as an element inside another set. Neither of those is possible with a regular mutable set.

Adding and Removing Elements

The Python tutorial on data structures covers the full set of modification methods.

Adding elements

s = {1, 2, 3}
s.add(4)              # adds one element  → {1, 2, 3, 4}
s.update([5, 6, 7])   # adds from list    → {1, 2, 3, 4, 5, 6, 7}
s.update({8}, (9,))   # multiple iterables at once
  • add(x) — inserts x. If x is already in the set, nothing happens.
  • update(iterable, ...) — inserts every element from each iterable passed. Accepts multiple arguments, each of which can be a list, set, tuple, or other iterable.

Removing elements

s = {"Python", "Java", "C++"}

s.remove("Java")   # removes "Java"; raises KeyError if not found
s.discard("Ruby")  # no error even if "Ruby" is absent
elem = s.pop()     # removes and returns an arbitrary element
s.clear()          # empties the set → set()

Decision rule: use discard() when a missing element is not a bug. Use remove() when a missing element means something went wrong and you want the KeyError to surface the problem immediately. Use pop() only when you need to consume one element and do not care which one.

Set Operations with Examples

Given two sets:

a = {1, 2, 3, 4}
b = {3, 4, 5, 6}

All four standard set operations, with both the operator and method forms:

# Union — all unique elements from both sets
result = a | b          # {1, 2, 3, 4, 5, 6}
result = a.union(b)     # same

# Intersection — elements in both sets
result = a & b              # {3, 4}
result = a.intersection(b)  # same

# Difference — elements in a but not in b
result = a - b              # {1, 2}
result = a.difference(b)    # same

# Symmetric difference — elements in exactly one of the two sets
result = a ^ b                        # {1, 2, 5, 6}
result = a.symmetric_difference(b)    # same

Summary of results:

OperationResult
Union{1, 2, 3, 4, 5, 6}
Intersection{3, 4}
Difference (a minus b){1, 2}
Symmetric difference{1, 2, 5, 6}

Note on direction: a - b and b - a produce different results. Symmetric difference (a ^ b) gives what is in one set or the other but not both, regardless of direction.

Each operation also has an in-place form that modifies the left-hand set directly, avoiding creation of a new object:

a |= b   # union in place
a &= b   # intersection in place
a -= b   # difference in place
a ^= b   # symmetric difference in place

Worked example: two groups of student IDs. One group attempted a mock test; the other completed the full course. Find those who appear in both.

attempted_mock   = {101, 102, 103, 104, 105}
completed_course = {103, 104, 105, 106, 107}

did_both       = attempted_mock & completed_course
# → {103, 104, 105}

only_attempted = attempted_mock - completed_course
# → {101, 102}

only_course    = completed_course - attempted_mock
# → {106, 107}

Intersection returns students who took both paths. Difference, applied in either direction, isolates one group.

Practical Patterns and Set Comprehensions

Deduplication

names        = ["Alice", "Bob", "Alice", "Charlie", "Bob"]
unique_names = list(set(names))
# → ['Alice', 'Bob', 'Charlie']  (order not guaranteed)

Converting a list to a set and back is the standard deduplication one-liner. The resulting list has no guaranteed order, so add sorted() if you need a consistent sequence.

Fast membership testing

allowed_users = {"[email protected]", "[email protected]", "[email protected]"}
incoming      = "[email protected]"

if incoming in allowed_users:
    print("Access granted")
else:
    print("Unauthorised")

The in check on a set is O(1) average regardless of how many users are in allowed_users.

Set comprehensions

squares      = {x**2 for x in range(1, 6)}
# → {1, 4, 9, 16, 25}

even_squares = {x**2 for x in range(1, 11) if x % 2 == 0}
# → {4, 16, 36, 64, 100}

Set comprehensions follow the same syntax as list comprehensions. Curly braces replace square brackets, and the result is a set, so duplicates are dropped automatically. Because curly braces have special meaning in MDX and JSX, every set comprehension in documentation must live inside a fenced code block, not in bare prose.

Counting unique characters

word           = "mississippi"
unique_chars   = set(word)
# → {'m', 'i', 's', 'p'}

distinct_count = len(set(word))
# → 4

This pattern solves placement questions that ask for the number of distinct characters in a string. The answer is a single expression: len(set(word)).

String-based set operations connect naturally to palindrome-checking problems, where sets help identify whether a string’s characters can be rearranged symmetrically. The palindrome string guide covers those patterns in detail.

Where Sets Appear in Placement Tests and Interviews

Three question types come up most often in online tests and technical rounds at service-sector companies:

  • Common elements between two arrays — maps directly to intersection. Convert both arrays to sets, apply &.
  • Elements unique to one side — use difference (a - b) or symmetric difference (a ^ b) depending on whether both directions matter.
  • Deduplication before sorting or counting — convert input list to set, convert back to list, then proceed.

Interviewers at product and analytics companies often combine set questions with hash-map questions, since sets and dictionaries share the same underlying hash-table structure. For a broader look at data-structures interview patterns (trees, stacks, and hash maps alongside sets), the FACE Prep data structures interview guide covers the full spread. Array-based problems that appear in the same coding rounds are covered in the find smallest and largest element in an array guide.

Deduplication with set() and O(1) membership testing are the same operations used in data-cleaning pipelines that feed LLM applications. If you want to apply Python fundamentals like these inside working AI projects, TinkerLLM at ₹299 is a practical next step. It runs from Python basics through to building retrieval-augmented applications.

Primary sources

Frequently asked questions

Can a Python set contain duplicate elements?

No. When you pass duplicates to a set, Python silently discards them. Constructing a set from the list [1, 1, 2] produces a set containing only 1 and 2.

What is the difference between remove() and discard() in Python sets?

remove() raises a KeyError if the element is not present; discard() does nothing in that case. Use discard() when you are not certain the element exists.

Why can't I use a list as a set element?

Sets require every element to be hashable. Lists are mutable and not hashable, so Python raises a TypeError. Use a tuple or frozenset instead.

Is set membership testing faster than list membership testing in Python?

Yes. The in operator on a set runs in O(1) average time because sets use a hash table internally. The same operation on a list is O(n), because Python checks each element in sequence until it finds a match.

How do I create an empty set in Python?

Use set(), not curly braces. An empty pair of curly braces creates an empty dictionary, not an empty set.

Can a Python set hold elements of different types?

Yes, provided every element is hashable. A single set can simultaneously hold integers, strings, and tuples.

Build AI projects

A self-paced playground for building with LLMs.

TinkerLLM is FACE Prep's sister property. A guided environment for shipping real LLM applications, the kind of project that earns a paragraph on your resume, not a line.

Try TinkerLLM (₹299 launch)
Free AI Roadmap PDF