List vs set in Python comes down to this: a list keeps items in order and allows duplicates, while a set stores only unique items, has no positions, and checks membership much faster. Pick a list for sequences, a set for uniqueness and lookups:
cities = ["Austin", "Denver", "Austin"] # ordered, duplicates kept
unique = {"Austin", "Denver"} # unordered, unique
I timed and printed every comparison below on Python 3.12.5, using US cities and fake customer emails.
We’ll compare order and duplicates, what can go inside each, lookup speed, set math for comparing groups, removing duplicates while keeping order, and memory use.
List vs set: the key differences
| List | Set | |
|---|---|---|
| Syntax | [1, 2, 3] | {1, 2, 3} (empty: set()) |
| Order | Kept | Not guaranteed |
| Duplicates | Allowed | Removed automatically |
Indexing x[0] | Yes | No |
x in ... speed | Slower as it grows (O(n)) | Fast on average (O(1)) |
| Items must be hashable | No | Yes |
| Set math (union etc.) | No | Yes |
Order, duplicates and indexing
Turn the same data into a list and a set and you’ll see the differences right away. The set drops repeats and has no first item, so indexing fails:
visits = ["Austin", "Denver", "Austin", "Boston", "Denver", "Austin"]
as_list = list(visits)
as_set = set(visits)
print("list:", as_list, len(as_list)) # keeps order and duplicates
print("set: ", as_set, len(as_set)) # unique items, no guaranteed order
print(as_list[0]) # lists have positions
try:
as_set[0]
except TypeError as err:
print("TypeError:", err)
Output:
list: ['Austin', 'Denver', 'Austin', 'Boston', 'Denver', 'Austin'] 6
set: {'Denver', 'Boston', 'Austin'} 3
Austin
TypeError: 'set' object is not subscriptable

The set’s printed order can differ from run to run for strings, so never rely on it. For more on sets themselves, see set vs tuple in Python.
What can go in a list vs a set?
You can put anything in a list. A set only holds hashable items, which rules out lists and dicts. Convert inner lists to tuples first:
coords = [[30.27, -97.74], [39.74, -104.99]]
try:
unique = set(coords) # lists can't go inside a set
except TypeError as err:
print("TypeError:", err)
unique = set(map(tuple, coords)) # tuples can
print(unique)
lookup = {("Austin", "TX"): 979_882} # tuples also work as dict keys
print(lookup[("Austin", "TX")])
Output:
TypeError: unhashable type: 'list'
{(30.27, -97.74), (39.74, -104.99)}
979882
Which is faster, a list or a set?
When you check whether something is present, I’d pick a set every time; it wins by a mile. A list scans items one at a time, while a set uses a hash table to jump to the answer:
import timeit
emails = [f"user{i}@example.com" for i in range(200_000)]
email_list = emails
email_set = set(emails)
target = "user199999@example.com" # worst case for the list: the last item
t_list = timeit.timeit(lambda: target in email_list, number=200)
t_set = timeit.timeit(lambda: target in email_set, number=200)
print(f"in list: {t_list * 1000:8.2f} ms for 200 lookups")
print(f"in set: {t_set * 1000:8.3f} ms for 200 lookups")
Output:
in list: 388.67 ms for 200 lookups
in set: 0.012 ms for 200 lookups

Lists are still fast for looping and for small collections. The rule of thumb: if you test in repeatedly on big data, convert to a set once. More in what in means in Python.
Comparing groups with set operations
Sets do the math you’d find awkward with lists: who’s on both lists, either list, or only one. These read almost like plain English:
newsletter = {"ann@example.com", "bo@example.com", "cy@example.com", "di@example.com"}
customers = {"bo@example.com", "di@example.com", "ed@example.com"}
print("both: ", sorted(newsletter & customers)) # intersection
print("either: ", sorted(newsletter | customers)) # union
print("subscribers only: ", sorted(newsletter - customers)) # difference
print("in exactly one: ", sorted(newsletter ^ customers)) # symmetric difference
print("customers all subscribed?", customers <= newsletter)
Output:
both: ['bo@example.com', 'di@example.com']
either: ['ann@example.com', 'bo@example.com', 'cy@example.com', 'di@example.com', 'ed@example.com']
subscribers only: ['ann@example.com', 'cy@example.com']
in exactly one: ['ann@example.com', 'cy@example.com', 'ed@example.com']
customers all subscribed? False

&, |, - and ^ answer marketing questions in one line each.Removing duplicates from a list (and keeping order)
set(items) removes duplicates but scrambles the order. dict.fromkeys() removes them and keeps the first-seen order, because dictionaries preserve insertion order:
orders = ["A102", "A101", "A102", "A105", "A101", "A103"]
print(list(set(orders))) # unique, but order is lost
print(list(dict.fromkeys(orders))) # unique AND in first-seen order
print(sorted(set(orders))) # unique and sorted
Output:
['A101', 'A105', 'A103', 'A102']
['A102', 'A101', 'A105', 'A103']
['A101', 'A102', 'A103', 'A105']

dict.fromkeys() when order matters and sorted(set()) when you want them sorted.There’s a full guide on merging lists without duplicates too.
Memory: sets cost more
Your set’s hash table needs extra room to stay fast, so it uses noticeably more memory than a list of the same numbers:
import sys
n = 100_000
data = list(range(n))
print(f"list of {n:,}: {sys.getsizeof(data):>9,} bytes")
print(f"set of {n:,}: {sys.getsizeof(set(data)):>9,} bytes")
Output:
list of 100,000: 800,056 bytes
set of 100,000: 4,194,520 bytes
I think that trade-off is usually worth it for lookups. If you only ever loop over the data, a list is leaner.
When to use a list vs a set
| Use a list when | Use a set when |
|---|---|
| Order matters | You only care about unique values |
| You need duplicates | You test membership often |
| You access items by position | You compare groups (union, intersection) |
| You sort or slice the data | You want to drop duplicates fast |
More on Python collections:
Frequently asked questions
What’s the difference between a list and a set in Python?
A list is ordered and allows duplicates. A set is unordered, holds only unique hashable items, and checks membership much faster.
Is a set faster than a list in Python?
For in checks, yes, by a wide margin on large data. For looping over every item, they’re similar.
How do I convert a list to a set?
Call set(my_list). Use list(my_set) to go back, remembering the order may change.
Why can’t I put a list in a set?
Lists are mutable and unhashable. Convert them to tuples first.
How do I remove duplicates from a list but keep the order?
Use list(dict.fromkeys(my_list)).
Where are sets documented?
See Sets in the Python tutorial.

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