Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

A Python set is an unordered collection of distinct, hashable objects. Use sets when you need fast-style membership logic, duplicate removal, or mathematical operations such as union and intersection. Create a populated set with braces or set(iterable); create an empty set with set(), because {} creates an empty dictionary.

What is a set in Python?

The Python tutorial defines a set as “an unordered collection with no duplicate elements.” A set object contains only distinct hashable values, so inserting an existing value has no additional effect.

numbers = {1, 2, 3, 2}
print(numbers)          # {1, 2, 3}
print(2 in numbers)     # True

Sets are useful for membership checks, removing repeated values, and comparing groups of data. They do not support positional indexing or slicing, and Python makes no ordering guarantee when a set is displayed or iterated. If output order matters, make it explicit with sorted().

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
tags = {"python", "api", "web"}
print(sorted(tags))     # deterministic presentation order

Creating sets correctly

Set literals

colors = {"red", "green", "blue"}
ids = {101, 102, 103}

Constructing from an iterable

set() accepts an iterable such as a list, tuple, string, or generator. Duplicate input values are collapsed.

from_iterable = set(["red", "red", "blue"])
print(from_iterable)    # {'red', 'blue'}

letters = set("banana")
print(letters)           # distinct characters; order is unspecified

Creating an empty set

empty = set()
print(type(empty))      # <class 'set'>

not_a_set = {}
print(type(not_a_set))  # <class 'dict'>

Use set() whenever you need an empty set. Braces without elements are reserved for an empty dictionary.

What can a set contain?

Every element must be hashable. Immutable built-in values such as numbers, strings, tuples (when their contents are hashable), and frozenset qualify. Mutable lists, dictionaries, and ordinary sets do not.

valid = {(1, 2), "text", 42}

# This raises TypeError: unhashable type: 'list'
# invalid = {[1, 2]}

Hashability lets Python place values in the set’s internal structure. A tuple containing a list is also invalid because the tuple’s contents are not all hashable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

frozenset: an immutable set

frozenset has set operations but cannot be changed after creation. Because it is immutable and hashable, it can be nested in another set or used as a dictionary key.

immutable = frozenset([1, 2, 3])
container = {immutable}
lookup = {immutable: "a dictionary value"}
print(immutable)
print(lookup[immutable])

Choose a normal set for a collection you will update. Choose frozenset for a fixed group that must itself be stored in a set or used as a mapping key.

Union, intersection, difference, and symmetric difference

Set operators make group comparisons concise. Given the following sets:

a = {1, 2, 3}
b = {3, 4, 5}
Operation Operator Result Meaning
Union a | b {1, 2, 3, 4, 5} Every value in either set
Intersection a & b {3} Values common to both
Difference a - b {1, 2} Values in a but not b
Symmetric difference a ^ b {1, 2, 4, 5} Values in exactly one set
union = a | b
common = a & b
only_a = a - b
either = a ^ b

# Named methods express the same operations
common_again = a.intersection(b)
new_values = a.union(b)
removed = a.difference(b)
exclusive = a.symmetric_difference(b)

Named methods are often clearer when an expression combines several operations or when you are passing an iterable rather than writing an operator expression.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Subset and superset tests

is_subset = {1, 2} <= a       # True
is_superset = a >= {1, 2}     # True
strict_subset = {1, 2} < a   # True: not equal to a

<= means every element on the left is in the right. The strict form < additionally requires the sets to differ.

Changing a set safely

Add one or many values

items = {"a", "b"}
items.add("c")
items.update(["d", "e"])
print(items)

add() inserts one element. update() consumes an iterable and inserts each of its elements; passing a string therefore adds individual characters.

Remove values

items.discard("missing")    # does nothing if absent

# items.remove("missing")   # raises KeyError if absent
removed = items.pop()       # removes an arbitrary element
items.clear()               # removes everything

Use discard() when absence is normal. Use remove() when absence indicates a bug you want to detect. pop() does not promise which element is removed, because sets are unordered; do not use it to retrieve a predictable “first” value.

Set comprehensions

A set comprehension follows the for/if pattern of a list comprehension while producing a set. The result is automatically deduplicated.

words = ["cat", "car", "dog", "cat"]
c_words = {word for word in words if word.startswith("c")}
print(c_words)             # {'cat', 'car'}

You can transform values as well as filter them:

raw = [" Alice ", "alice", "Bob"]
names = {name.strip().lower() for name in raw}
print(names)               # {'alice', 'bob'}

Keep comprehensions readable. If the expression needs several statements or side effects, use a regular loop and make the intermediate steps explicit.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Set versus list, tuple, and dictionary

Type Duplicates Order and indexing Mutability Typical purpose
Set Not allowed Unordered; no indexing or slicing Mutable Uniqueness, membership, set algebra
List Allowed Sequence; supports indexing and slicing Mutable Ordered collection and repeated values
Tuple Allowed Sequence; supports indexing and slicing Immutable Fixed records or hashable sequences
Dictionary Keys are unique Key-based access; stores insertion order Mutable Mapping keys to values

Convert a list to a set when uniqueness matters and sequence order does not. If you must preserve the first-seen order while removing duplicates, a set alone is not the right output structure; use a separate “seen” set while building a list.

values = [3, 1, 3, 2, 1]
seen = set()
ordered_unique = []
for value in values:
    if value not in seen:
        seen.add(value)
        ordered_unique.append(value)
print(ordered_unique)       # [3, 1, 2]

Common mistakes and troubleshooting

Using braces for an empty set

Symptom: methods or type checks behave as if the object were a dictionary. Fix: write empty = set().

Trying to index a set

values = {10, 20, 30}
# values[0]                 # TypeError: 'set' object is not subscriptable
first_for_display = sorted(values)[0]

Sorting creates a list for deterministic access; it does not make the original set ordered.

Adding an unhashable value

Symptom: TypeError: unhashable type: 'list' (or dictionary/set equivalent). Fix: use an immutable representation such as a tuple or frozenset, provided all nested values are hashable.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Expecting pop() to remove a known item

Symptom: a different value disappears between runs or environments. Fix: call remove(value) or discard(value) when the target is known.

Changing a set while iterating

Do not add or remove elements from a set during a loop over that same set; Python can raise a runtime error. Iterate over a snapshot such as set(values) or collect changes and apply them afterward.

Confusing equality with identity

Set membership uses value equality and hashing. Two separately created, equal immutable values represent the same set element; object identity is not the criterion.

Practical patterns

Remove duplicates from a list

duplicates = ["a", "b", "a", "c", "b"]
unique = set(duplicates)
print(unique)

This intentionally discards order. Use the ordered pattern shown earlier when order is part of the requirement.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Find common permissions

editor = {"read", "write", "comment"}
viewer = {"read", "comment"}
shared = editor & viewer
missing_for_viewer = editor - viewer

Check whether all required values exist

required = {"id", "email"}
received = {"id", "email", "name"}
if required <= received:
    print("All required fields are present")
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance and reliability considerations

Sets are designed for membership and algebra operations, but the official documentation cited for this guide does not provide a universal numeric benchmark. Actual timing depends on Python version, data shape, hashing cost, and workload. Measure your own application if performance is a requirement rather than assuming a fixed speedup.

  • Store only hashable values and ensure custom objects implement consistent hashing and equality.
  • Use sorted(my_set) at output boundaries when reproducible text, JSON preparation, or tests require stable ordering.
  • Do not serialize a set directly as JSON; convert it to a list and choose whether to sort it first.
  • For immutable composite membership, use frozenset and document that callers cannot mutate it.

Or skip the browser setup

If your Python workflow also needs rendered screenshots of documentation, dashboards, or result pages, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status.

One request is enough:

import requests
r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://python.org"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

See the ScreenshotNeo documentation for all options, including PNG, JPEG, WebP, PDF, full-page capture, CSS selectors, custom JavaScript, device presets, cookies, headers, caching, asynchronous jobs, signed webhooks, bulk capture, and usage reporting. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.

The Free plan includes 1,000 screenshots each month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently Asked Questions

Can a set contain another set?

No. A mutable set is unhashable, so it cannot be an element of another set. Use a frozenset when a nested set-like value is required.

How do I get a deterministic representation of a set?

Use sorted(my_set) to create an ordered list before displaying, testing, or serializing the values.

What does symmetric difference return?

It returns values present in exactly one of the two sets, using the ^ operator or symmetric_difference() method.

When should I use a tuple instead of a frozenset?

Use a tuple when sequence order and positional meaning matter; use a frozenset when membership and uniqueness matter and order does not.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.