To create an empty set in Python, call set() with no arguments. Don’t write {}: empty curly braces give you an empty dictionary, not a set. Here’s the one line you need:
visited_states = set() # empty set
not_a_set = {} # empty dict!
Tested on Python 3.12.5: the screenshots and printed results below are the genuine output, not something typed by hand.
We’ll go through the set() constructor, the curly-brace trap, filling a set with add() and comprehensions, checking for emptiness, and the safe way to use an empty set as a default argument.
Create an empty set with set()
The set() constructor with nothing inside it returns a brand-new, empty, mutable set. Python even prints it as set(), because there’s no literal for an empty set:
visited_states = set()
print(visited_states) # set()
print(type(visited_states)) # <class 'set'>
print(len(visited_states)) # 0
print(bool(visited_states)) # False
Output:
set()
<class 'set'>
0
False

set(), its type is set, its length is 0 and it’s falsy.Sets hold unique, unordered, hashable items. If you’re not sure a set is the right container, my comparison of Python sets vs tuples shows where each one fits.
Why doesn’t {} create an empty set in Python?
Curly braces were used for dictionaries long before sets got their own literal syntax, so {} stayed a dict. A set literal like {"Ohio"} works only when there’s at least one item inside:
a = {}
b = set()
print(type(a), type(b))
print(a == b)
c = {*()} # unpacking an empty tuple also gives a set
print(type(c), c)
a.add("Texas") # a dict has no .add()
Output:
<class 'dict'> <class 'set'>
False
<class 'set'> set()
Traceback (most recent call last):
File "C:\pyguides\braces_dict.py", line 9, in <module>
a.add("Texas") # a dict has no .add()
^^^^^
AttributeError: 'dict' object has no attribute 'add'

{} reports dict, the two empties aren’t equal, and .add() fails with an AttributeError.That AttributeError is the usual symptom: the code looks fine until the first add(). The {*()} trick does build an empty set, but set() is clearer, so I stick with it.
If an empty dictionary is what you actually wanted, see creating an empty dictionary in Python.
Add items to an empty set with add() and update()
Once the set exists, add() inserts one item and update() inserts everything from an iterable. Duplicates are dropped silently, which is the main reason to start with a set in the first place:
visited_states = set()
visited_states.add("Texas")
visited_states.add("Ohio")
visited_states.add("Texas") # duplicate, ignored
print(sorted(visited_states))
visited_states.update(["Utah", "Ohio", "Maine"])
print(sorted(visited_states), len(visited_states))
Output:
['Ohio', 'Texas']
['Maine', 'Ohio', 'Texas', 'Utah'] 4
Adding Texas twice still leaves one Texas, and update() skips the Ohio that’s already there. For more ways to insert items, read adding items to a set in Python.
Build a set from data with a loop or a set comprehension
In real code, an empty set is usually a starting point that a loop fills. Here I collect the customers who placed an order over $100.00 in the first week of October 2026:
orders = [
("2026-10-05", "Emily", 129.99),
("2026-10-05", "James", 45.50),
("2026-10-06", "Emily", 18.25),
("2026-10-06", "Olivia", 210.00),
("2026-10-07", "James", 150.75),
]
big_spenders = set()
for day, customer, amount in orders:
if amount > 100:
big_spenders.add(customer)
print("loop: ", sorted(big_spenders))
same = {customer for _, customer, amount in orders if amount > 100}
print("comprehension:", sorted(same))
none_found = {c for _, c, amount in orders if amount > 500}
print("no matches: ", none_found)
Output:
loop: ['Emily', 'James', 'Olivia']
comprehension: ['Emily', 'James', 'Olivia']
no matches: set()

set().Notice that a comprehension with no matches still returns an empty set, not a dict, so it’s safe to call add() on the result later.
When you already have a list, skip the loop and pass it straight in; converting a list to a set in Python covers that, including what happens to order.
How do you check if a set is empty?
An empty set is falsy, so if not my_set is the idiomatic test. Comparing with set() works too, but comparing with {} quietly returns False:
alerts = set()
if not alerts:
print("No alerts yet")
print(len(alerts) == 0, alerts == set(), alerts == {})
alerts.add("Low stock: SKU-1042")
if alerts:
print(f"{len(alerts)} alert(s):", alerts)
Output:
No alerts yet
True True False
1 alert(s): {'Low stock: SKU-1042'}
That last comparison is another reason the dict/set mix-up hurts. There are more ways to test this in checking if a Python set is empty.
Create an empty frozenset and use set() as a default argument
frozenset() gives you an empty set that can’t change, which is handy as a dictionary key or a constant. An empty set and an empty frozenset compare equal:
empty_frozen = frozenset()
print(empty_frozen, type(empty_frozen).__name__)
print(set() == frozenset())
def tag_order(order_id, tags=None):
if tags is None:
tags = set() # a fresh empty set on every call
tags.add("reviewed")
return order_id, sorted(tags)
print(tag_order("A-101"))
print(tag_order("A-102"))
print(tag_order("A-103", {"rush"}))
Output:
frozenset() frozenset
True
('A-101', ['reviewed'])
('A-102', ['reviewed'])
('A-103', ['reviewed', 'rush'])

frozenset() equals set(), and each call that omits tags starts again from an empty set.Never write def tag_order(order_id, tags=set()). The default is created once, so every call would share and grow the same set. Use None and create the set inside the function.
The reason behind that trap is how Python treats changeable objects, explained in mutable vs immutable types in Python.
Empty set syntax compared
| Code | What you get | Can add items? |
|---|---|---|
set() | Empty set | Yes |
{} | Empty dict | No (AttributeError on add) |
{*()} | Empty set | Yes, but it’s hard to read |
frozenset() | Empty frozen set | No, it’s immutable |
{x for x in data if ...} | Set, empty when nothing matches | Yes |
Want to keep working with sets? Pick one of these:
- Remove an item from a set in Python
- Convert a set to a list in Python
- Build a dictionary of sets in Python
- Create an empty array in Python
Frequently asked questions
How do I create an empty set in Python?
Call set() with no arguments, for example tags = set().
Why is {} not an empty set?
Empty curly braces create an empty dictionary. Set literals need at least one item, like {"Ohio"}.
How do I add elements to an empty set?
Use add() for one item and update() for an iterable. Duplicates are ignored.
How do I check if a set is empty?
Use if not my_set: or len(my_set) == 0. Don’t compare it with {}.
Can I use set() as a default argument?
Avoid it, because the default is shared between calls. Use None and create the set inside the function.
Where are Python sets documented?
See set and frozenset types in the Python docs.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He started out building .NET and SharePoint solutions at HP, TCS and KPIT before moving into Python, machine learning and AI, and he also builds web apps with TypeScript and React. He writes the tutorials here himself, and every example is run before publishing so you see the real output. More about Bijay · Microsoft MVP profile · LinkedIn