5 Powerful Facts About Sets in Python

Sets in Python

Sets in Python are a built-in collection type designed to store unique values and perform fast membership checks.

A set is an unordered collection of unique values. Unlike a list, a set automatically throws away duplicates and doesn’t remember any particular order for its items – what it offers instead is extremely fast membership testing and a full set of mathematical operations borrowed directly from set theory: union, intersection, difference, and symmetric difference.

Creating a Set

fruits = {'apple', 'banana', 'cherry', 'apple'}
print(fruits)          # {'apple', 'banana', 'cherry'}  – the duplicate is gone
print(len(fruits))     # 3

A set is written with curly braces, the same as a dictionary, but holds bare values instead of key-value pairs. There’s one important exception to remember: {} on its own creates an empty dictionary, not an empty set, because Python reserves the bare curly braces for dictionaries by default. An empty set has to be created with the set() function instead.

empty_dict = {}          # this is a dictionary
empty_set = set()         # this is an empty set

numbers = set([1, 2, 2, 3, 3, 3])
print(numbers)            # {1, 2, 3}

Adding, Removing, and Checking Membership

fruits = {'apple', 'banana'}
fruits.add('cherry')
fruits.discard('banana')
print(fruits)                    # {'apple', 'cherry'}
print('apple' in fruits)         # True

discard() removes an item if it’s present and does nothing if it isn’t; the closely related remove() does the same job but raises a KeyError if the item is missing, so discard() is the safer default unless a missing item genuinely signals a bug worth catching. Checking membership with in is where sets truly distinguish themselves from lists: because a set is built internally as a hash table rather than a plain sequence, checking whether a value is present takes roughly the same tiny amount of time no matter how large the set is, while checking membership in a list gets slower as the list grows, since Python may have to scan every single element.

Union: Combining Two Sets

The union of two sets contains every element that appears in either one, with duplicates automatically collapsed. Python offers both a method and an operator for it.

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

print(a.union(b))    # {1, 2, 3, 4, 5}
print(a | b)          # {1, 2, 3, 4, 5}  – same result

Intersection: What They Share

The intersection keeps only the elements present in both sets at once.

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

print(a.intersection(b))    # {3}
print(a & b)                 # {3}  – same result

Difference: What’s in One but Not the Other

The difference keeps whatever is in the first set but not in the second – and because of that, unlike union and intersection, the order you write it in changes the answer.

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

print(a.difference(b))    # {1, 2}   – in a, not in b
print(b.difference(a))    # {4, 5}   – in b, not in a
print(a - b)               # {1, 2}  – same as a.difference(b)

Symmetric Difference: Everything Except What They Share

The symmetric difference keeps everything that’s in exactly one of the two sets, excluding whatever overlaps between them – effectively the union with the intersection removed.

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

print(a.symmetric_difference(b))    # {1, 2, 4, 5}
print(a ^ b)                         # {1, 2, 4, 5}  – same result

These four operations turn tasks that would otherwise require nested nested loops and manual bookkeeping – find everyone who appears in both lists, find everyone who’s only in one, and so on – into a single, direct expression that says exactly what it means.

A Practical Use: Removing Duplicates

Because a set can never contain duplicates, converting a list to a set and back is a common, quick way to strip repeated values out of a collection.

names = ['Ali', 'Sara', 'Ali', 'Bilal', 'Sara']
unique_names = list(set(names))
print(unique_names)   # order not guaranteed, but no duplicates

Worth remembering: this trick only works cleanly if the original order doesn’t matter, since sets don’t preserve the sequence items were added in. If you need to remove duplicates while keeping the original order intact, a small loop that checks membership in a set (fast) while still building an ordinary list (ordered) does the job instead.

Set Comprehensions

Just like list comprehensions and dictionary comprehensions, a set can be built in one line with a comprehension – swap the square brackets for curly braces.

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_squares = {n * n for n in numbers if n % 2 == 0}
print(even_squares)   # {4, 16, 36, 64, 100}

As with any set, the result has no guaranteed order and automatically drops any duplicate values the expression happens to produce.

Sets Are Mutable, Their Elements Must Not Be

A set itself can be changed after creation – items can be added and removed freely – but every individual element inside it must be an immutable type: numbers, strings, and tuples are all allowed, but a list can never be placed inside a set, for exactly the same underlying reason a list can never be used as a dictionary key – Python needs every element’s value to stay fixed once it’s been hashed and filed into the set’s internal structure.

valid = {1, 'two', (3, 4)}     # fine – number, string, tuple
invalid = {1, [2, 3]}          # raises TypeError – a list can't go inside a set

If you need an immutable, hashable set-like object – one that could itself sit inside another set, for instance – Python provides frozenset(), which behaves exactly like a set but, once created, can’t be changed.

No Comments

Leave a Reply

Recent Comments

No comments to show.