Python Set Data Structure

Learn Python Set Data Structure with practical examples, explanations, best practices, and real-world coding techniques.

A set in Python is a mutable collection used to store unique elements. Unlike a list, a set does not maintain elements as an index-based sequence, and duplicate values are automatically eliminated.

Sets are especially useful when a program needs fast average-case membership testing, duplicate removal, or mathematical operations such as union, intersection, difference, and symmetric difference.

Python also provides frozenset, an immutable version of a set that can be used in situations where the set itself needs to be hashable.

Creating a Set in Python

A set can be created using curly braces with comma-separated values.

languages = {"Python", "JavaScript", "Java"}

print(languages)

Duplicate values are automatically removed.

numbers = {10, 20, 10, 30, 20}

print(numbers)

The resulting set contains each distinct value only once.

Creating an Empty Set

An important detail is that {} creates an empty dictionary, not an empty set. Use set() to create an empty set.

empty_set = set()
empty_dictionary = {}

print(empty_set)
print(empty_dictionary)

Adding Elements to a Set

The add() method inserts one element into a set. If the element already exists, the set remains unchanged.

skills = {"Python", "SQL"}

skills.add("Git")
skills.add("Python")

print(skills)

Adding Multiple Elements

The update() method adds elements from another iterable to the set.

skills = {"Python", "SQL"}

skills.update(["Git", "Docker", "Python"])

print(skills)

Removing Elements from a Set

remove()

The remove() method removes a specified element. It raises a KeyError if the element does not exist.

skills = {"Python", "SQL", "Git"}

skills.remove("SQL")

print(skills)

discard()

The discard() method also removes an element, but it does not raise an exception when the element is missing.

skills = {"Python", "SQL", "Git"}

skills.discard("SQL")
skills.discard("Docker")

print(skills)

pop()

The pop() method removes and returns an arbitrary element from the set. Since sets are not index-based sequences, you should not rely on which element will be removed.

skills = {"Python", "SQL", "Git"}

removed = skills.pop()

print("Removed:", removed)
print("Remaining:", skills)

clear()

The clear() method removes all elements from the set.

skills = {"Python", "SQL", "Git"}

skills.clear()

print(skills)

Checking Membership in a Set

The in operator is one of the most useful operations on a set. It checks whether a value exists in the collection.

skills = {"Python", "SQL", "Docker"}

print("Python" in skills)
print("Java" in skills)

Set membership testing is typically O(1) on average, making sets useful when the same membership check needs to be performed many times.

Finding the Size of a Set

Use the built-in len() function to find the number of unique elements in a set.

numbers = {10, 20, 30, 40}

print(len(numbers))

Iterating Over a Set

A set can be traversed with a for loop. Since a set is not an index-based sequence, iteration should not depend on a particular order.

skills = {"Python", "SQL", "Git"}

for skill in skills:
    print(skill)

Set Union

The union of two sets contains every unique element found in either set.

You can use the | operator or the union() method.

frontend = {"HTML", "CSS", "JavaScript"}
backend = {"Python", "JavaScript", "C#"}

all_skills = frontend | backend

print(all_skills)

The result contains JavaScript only once even though it appears in both sets.

Set Intersection

The intersection contains only elements that exist in both sets.

frontend = {"HTML", "CSS", "JavaScript"}
backend = {"Python", "JavaScript", "C#"}

common = frontend & backend

print(common)

The & operator performs set intersection. The equivalent method is intersection().

Set Difference

The difference contains elements that exist in the first set but not in the second set.

frontend = {"HTML", "CSS", "JavaScript"}
backend = {"Python", "JavaScript", "C#"}

frontend_only = frontend - backend

print(frontend_only)

Difference is directional. A - B and B - A can produce different results.

Symmetric Difference

The symmetric difference contains elements that belong to either set, but not to both.

team_a = {"Python", "JavaScript", "SQL"}
team_b = {"JavaScript", "C#", "Docker"}

different = team_a ^ team_b

print(different)

Set Relationship Checks

Python provides methods for determining relationships between sets, including subset, superset, and disjoint checks.

required = {"Python", "SQL"}
available = {"Python", "SQL", "Docker"}

print(required.issubset(available))
print(available.issuperset(required))

mobile = {"Swift", "Kotlin"}

print(required.isdisjoint(mobile))

Set Comprehension

A set comprehension provides a concise way to create a set from an iterable. Duplicate results are automatically removed.

numbers = [1, 2, 2, 3, 4, 4, 5]

squares = {
    number * number
    for number in numbers
}

print(squares)

Set comprehensions are useful when both transformation and uniqueness are required.

Removing Duplicates from a List

One of the most common uses of a Python set is removing duplicate values from a list.

numbers = [10, 20, 10, 30, 20, 40]

unique_numbers = list(set(numbers))

print(unique_numbers)

This approach removes duplicates, but the resulting order should not be relied upon. If preserving the original order is important, a different approach should be used.

Removing Duplicates While Preserving Order

A dictionary can be useful when unique values must retain their first-seen order. Since modern Python dictionaries preserve insertion order, converting through dict.fromkeys() is a concise solution.

numbers = [10, 20, 10, 30, 20, 40]

unique_numbers = list(dict.fromkeys(numbers))

print(unique_numbers)

Set with Different Data Types

A set can contain different hashable Python objects. Strings, numbers, and tuples containing hashable elements can be set members.

items = {
    "Python",
    100,
    3.14,
    (10, 20)
}

print(items)

Mutable objects such as lists and dictionaries cannot be directly stored as set elements because they are not hashable.

Set vs List

Lists and sets are both useful collections, but they are designed for different purposes.

Feature List Set
Duplicates Allowed Not stored
Indexing Supported Not supported
Membership O(n) typical O(1) average
Ordering Ordered Not an index-based sequence
Primary use Sequences Uniqueness and membership

frozenset in Python

A frozenset is an immutable set. Its elements cannot be added or removed after creation.

permissions = frozenset({
    "read",
    "write"
})

print(permissions)

Because a frozenset is immutable and hashable when its elements are hashable, it can be used as a dictionary key or as an element of another set.

role_permissions = {
    frozenset({"read", "write"}): "Editor",
    frozenset({"read"}): "Viewer"
}

print(role_permissions[frozenset({"read", "write"})])

Set Time Complexity

Python sets are hash-table-based collections. Many common operations have O(1) average-case complexity.

Operation Average Complexity
Add O(1)
Remove O(1)
Membership check O(1)
Length O(1)
Iteration O(n)

Set union, intersection, and difference operations depend on the sizes of the sets involved. The exact cost can vary based on the operation and implementation.

Practical Example: Comparing Developer Skills

Sets are useful for comparing collections of unique values. For example, an application can determine which technologies are shared between two developers or which skills are unique to one developer.

developer_a = {
    "Python",
    "SQL",
    "Docker",
    "Git"
}

developer_b = {
    "Python",
    "JavaScript",
    "Git",
    "React"
}

common_skills = developer_a & developer_b
only_a = developer_a - developer_b
all_skills = developer_a | developer_b

print("Common:", common_skills)
print("Only A:", only_a)
print("All:", all_skills)

Common Set Mistakes in Python

  • Using {} when an empty set is required. Use set() instead.
  • Trying to access a set with an index such as my_set[0].
  • Assuming a particular iteration order for a set.
  • Using remove() when the element may not exist and an exception is not desired.
  • Assuming pop() removes the first or last element.
  • Trying to add mutable objects such as lists or dictionaries directly to a set.
  • Using a set when duplicate values or positional access are important.
  • Converting a list to a set without considering whether the original order must be preserved.

When Should You Use a Set?

A set is a good choice when uniqueness or membership testing is more important than maintaining an index-based sequence.

  • You need to store unique values.
  • You frequently check whether a value exists.
  • You need union, intersection, or difference operations.
  • You want to eliminate duplicate values.
  • You need to compare collections based on their members rather than positions.

Key Takeaways

  • Python sets store unique elements.
  • Sets do not provide normal index-based access.
  • Use set() to create an empty set because {} creates an empty dictionary.
  • add() inserts one element, while update() can add multiple elements.
  • remove() raises an exception for a missing element, while discard() does not.
  • Sets support union, intersection, difference, and symmetric difference operations.
  • Set membership testing is typically O(1) on average.
  • frozenset provides an immutable and hashable set-like collection.
  • Sets are useful for duplicate removal, membership testing, and comparing collections.
  • Use a list instead when ordering, duplicates, or index-based access are central to the problem.

Code Examples

skills = {"Python", "SQL"}

skills.add("Docker")
skills.update(["Git", "JavaScript"])

skills.discard("SQL")

print(skills)
    
frontend = {"HTML", "CSS", "JavaScript"}
backend = {"Python", "JavaScript", "C#"}

print("Union:", frontend | backend)
print("Intersection:", frontend & backend)
print("Frontend only:", frontend - backend)
print("Different:", frontend ^ backend)
    
numbers = [10, 20, 10, 30, 20, 40]

unique_numbers = list(set(numbers))

print(unique_numbers)
    
numbers = [1, 2, 2, 3, 4, 4, 5]

squares = {
    number * number
    for number in numbers
}

print(squares)
    
allowed_roles = {
    "Admin",
    "Editor",
    "Developer"
}

role = "Developer"

if role in allowed_roles:
    print("Access allowed")
else:
    print("Access denied")
    

Pro Tip

Use a Python set when the main requirement is uniqueness or fast average-case membership testing. If you also need predictable sequence order or index-based access, use a list instead. When removing duplicates, always consider whether preserving the original order matters.

🎨 IgKnight Docs

Master HTML, CSS, JS, Python, .NET and more with easy-to-follow lessons and practical code examples.

© 2025 IgKnight Learning Platform. All rights reserved.