Table of Contents

What Will You Learn
You’ll explore set creation, key operations like union, intersection, and difference, and learn how sets are used in real-world scenarios like filtering data or removing duplicates. It also covers immutable sets (frozensets) and highlights common beginner mistakes.


A set is a unique type of collection used when uniqueness of values matters and order does not. If you need to remove duplicates, compare two datasets, or perform intersections or differences — this is a job for set.

Sets are considered a fundamental tool in programming: they provide fast lookup, compact storage, and support for mathematical operations on sets. Working with sets is often easier than with lists when the order of elements is not important.

For beginners, understanding set is a step toward solving tasks more efficiently, such as filtering, analysis, access logic, and data comparison. This type is built into the language and supported at the syntax level.

What is Set Type in Python?

A set is a mutable, unordered collection type where all elements are unique. It is based on mathematical set theory and is used to store non-repeating values of any immutable type (numbers, strings, tuples).

fruits = {"apple", "banana", "orange"}

A set does not maintain the order of elements. When printed, the order may differ from the original — this is normal and not an error. Also, set automatically removes duplicates:


    nums = {1, 2, 2, 3, 4}
    print(nums)  # {1, 2, 3, 4}
  

Sets support operations such as union, intersection, difference, and symmetric difference. These operations are fast and reliable, making set a great choice for analyzing and comparing large data sets.

What is Set Items?

Set elements can be any immutable data types, such as:

  • int
  • float
  • str
  • bool
  • tuple (if the tuple does not contain mutable objects)

Mutable types like list, dict, set are not allowed as elements — doing so will raise a TypeError.


    my_set = {1, "two", (3, 4)}  # valid
    my_set = {1, [2, 3]}         # ❌ TypeError
  

All elements in a set must be unique. If you try to create or add a duplicate, it will be ignored. This makes set a handy tool for filtering, validation, and removing duplicates with minimal effort.

How to Create a Set in Python?

You can create a set in two main ways: using curly braces {} or with the built-in set() function. Both methods are used depending on the context.

Creating with curly braces


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

The output order may vary because the set is unordered.

Creating an empty set

empty_set = set()

Important: You cannot create an empty set with {} — this will create an empty dict.

Converting from a list, string, or other iterable


    unique_numbers = set([1, 2, 2, 3])       # {1, 2, 3}
    letters = set("hello")                   # {'e', 'o', 'l', 'h'}
  

The set() function automatically removes duplicates. This is useful when you need to obtain a set of unique values from input data.

How to Modify a Set?

A set is a mutable type, which means it can be updated, cleared, and changed in place. This makes set a convenient tool when building logic that needs to respond to changing data.

Adding an element: add()


    fruits = {"apple", "banana"}
    fruits.add("orange")
    print(fruits)  # {'apple', 'banana', 'orange'}
  

The add() method adds only one element. If it already exists, nothing happens.

Adding multiple elements: update()

fruits.update(["grape", "melon"])

update() accepts any iterable: list, string, set. All values are added to the set, and duplicates are automatically ignored.

Removing elements: remove() and discard()


    fruits.remove("apple")   # Removes, but raises an error if not present
    fruits.discard("kiwi")   # Removes, but no error if not present
  

Use discard() when you're not sure the element exists — it's safer.

Removing a random element: pop()


    item = fruits.pop()
    print(item)
  

The pop() method removes and returns a random element, since sets are unordered.

Clearing a set: clear()


    fruits.clear()
    print(fruits)  # set()
  

This clears the set entirely, leaving it empty.

Examples of set operations:


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

    print(a | b)   # union → {1, 2, 3, 4, 5}
    print(a & b)   # intersection → {3}
    print(a - b)   # difference → {1, 2}
    print(a ^ b)   # symmetric difference → {1, 2, 4, 5}
  

These operations are especially useful for analyzing overlaps, filtering data, and logically comparing collections.

Frozen Sets

A frozenset is an immutable version of a regular set (set). Once a frozenset is created, it cannot be changed: no adding, removing, or clearing. This makes it ideal for use as dictionary keys, set elements, constant collections, and in situations where structural integrity must be preserved.

How to create a frozenset:

immutable_colors = frozenset(["red", "green", "blue"])

It’s created using the built-in frozenset() function, which accepts any iterable. After creation, any modification attempts will raise an error:

immutable_colors.add("yellow")  # AttributeError

Use cases for frozenset:

  • Storing constant sets of values;
  • Using as dictionary keys (unlike regular set, which is unhashable);
  • Protecting data from accidental changes;
  • Performance optimization when working with large sets.

Comparison of set vs frozenset

Characteristic set frozenset
Mutable ✅ Yes ❌ No
Supports .add() ✅ Yes ❌ No
Supports .remove() ✅ Yes ❌ No
Supports .clear() ✅ Yes ❌ No
Can be a set element or dict key ❌ No ✅ Yes
Supports iteration (for in) ✅ Yes ✅ Yes
Used for protected collections ❌ No ✅ Yes

Beginner Mistakes

Working with sets may seem intuitive, but novice developers often encounter several problems. Below are common mistakes and their explanations with safe alternatives.

1. Using {} to create an empty set


    s = {}
    print(type(s))  # 
  

Solution:
Use set():

s = set()

2. Adding a mutable object to a set

my_set = {1, 2, [3, 4]}  # TypeError

Reason: list is a mutable type and cannot be used as a set element.

Solution: Use a tuple if you need to add multiple values as a single element:

my_set = {1, 2, (3, 4)}

3. Using set methods on a frozenset


    fs = frozenset([1, 2, 3])
    fs.add(4)  # AttributeError
  

Solution:
Understand that frozenset is immutable. If you need to add an element, create a new set:

new_fs = fs | {4}

4. Removing a non-existent element


    items = {"a", "b"}
    items.remove("z")  # KeyError
  

Solution:
Use discard() instead of remove():

items.discard("z")  # safe

5. Expecting order in output


    nums = {1, 2, 3}
    print(nums[0])  # TypeError
  

Reason: sets do not support indexing. Order is not guaranteed.

Solution:
If you need index-based access — convert to a list:

first = list(nums)[0]

Frequently Asked Questions

What is the main difference between a list and a set?

The main difference is uniqueness and order. A list preserves the order of elements and allows duplicates. A set does not preserve order and automatically removes duplicates. Sets are ideal for operations with unique values, while lists are used for ordered collections. A list supports indexing, but a set does not.

How to remove duplicates from a list using a set?

This is one of the most common and convenient uses of set. Simply convert the list to a set — duplicates will disappear:

unique_items = list(set(["a", "b", "a", "c"]))

If order matters — use dict.fromkeys() or additional libraries like collections.OrderedDict.

Can I sort a set?

Not directly. A set is unordered and cannot be sorted "in place." But you can create a sorted version using a temporary structure:

sorted_set = sorted(my_set)

The result is a list sorted in ascending order. If preserving order is important — use a list instead of a set.

What happens if I add a duplicate item to a set?

Nothing will happen — the duplicate will simply be ignored. A set always contains only unique values, and attempting to add an existing element will not raise an error, but also will not change the structure:


      s = {1, 2}
      s.add(2)
      print(s)  # {1, 2}
    
When should I use frozenset instead of set?

Use frozenset when you need to protect the structure from modification. For example, if you want to preserve a fixed set of parameters or use a set as a dictionary key. frozenset is also useful for safely passing data to other parts of the program where it should remain unchanged.

Can I convert a set back to a list or tuple?

Yes. Use the built-in functions list() or tuple():


      s = {"a", "b", "c"}
      lst = list(s)
      tup = tuple(s)
    

The order of elements will be random (due to the nature of set), but conversion is fast. This is convenient if you need to retain unique values and continue working with them in another format.