Four brackets, four behaviors. The list vs tuple vs set vs dictionary in Python choice comes down to three questions: can it change, does it keep order, and does it allow duplicates?
A list is changeable and ordered, and a tuple is fixed. A set keeps unique items only, while a dictionary maps keys to values:
[1, 2, 2] # list: ordered, changeable, duplicates OK
(1, 2, 2) # tuple: ordered, can't change
{1, 2} # set: unordered, unique items only
{"a": 1, "b": 2} # dict: key -> value, keys unique
I ran each snippet on Python 3.12.5 with a made-up coffee shop menu and a handful of US cities, so the outputs you see are copied from my console.
List vs tuple vs set vs dictionary at a glance
| Feature | List | Tuple | Set | Dictionary |
|---|---|---|---|---|
| Changeable | Yes | No | Yes (add/remove) | Yes |
| Ordered | Yes | Yes | No | Yes (insertion order) |
| Duplicates | Yes | Yes | No | Keys no, values yes |
| Access by | Index | Index | Membership only | Key |
Here are all four built from similar data. Watch the repeated Austin and TX:
cities = ["Austin", "Denver", "Austin", "Boston"] # list
point = (30.2672, -97.7431) # tuple
states = {"TX", "CO", "TX", "MA"} # set
prices = {"coffee": 4.50, "bagel": 3.25} # dictionary
for obj in (cities, point, states, prices):
print(f"{type(obj).__name__:<5} len={len(obj)} {obj}")
print(cities[0], point[1], prices["coffee"])
print("TX" in states, "bagel" in prices)
Output:
list len=4 ['Austin', 'Denver', 'Austin', 'Boston']
tuple len=2 (30.2672, -97.7431)
set len=3 {'CO', 'MA', 'TX'}
dict len=2 {'coffee': 4.5, 'bagel': 3.25}
Austin -97.7431 4.5
True True

The set printed its items in its own order, and yours may differ. If you’re deciding between just two of them, I compare them head to head in set vs tuple in Python.
Can you change a list, tuple, set or dictionary after creating it?
Lists, sets and dictionaries are mutable, so you can change them in place. A tuple is immutable, and you can’t replace its items:
cities = ["Austin", "Denver"]
cities.append("Boston")
cities[0] = "Dallas"
print(cities)
point = (30.2672, -97.7431)
try:
point[0] = 40.7128
except TypeError as e:
print("tuple:", e)
states = {"TX", "CO"}
states.add("MA")
print(sorted(states))
prices = {"coffee": 4.50}
prices["bagel"] = 3.25
prices["coffee"] = 4.75
print(prices)
Output:
['Dallas', 'Denver', 'Boston']
tuple: 'tuple' object does not support item assignment
['CO', 'MA', 'TX']
{'coffee': 4.75, 'bagel': 3.25}
Immutability has side effects worth knowing, like a tuple that holds a list. My guide to mutable vs immutable objects in Python walks through them, and creating a tuple in Python covers the syntax traps.
Order, duplicates and indexing in lists, tuples, sets and dictionaries
Lists and tuples keep items where you put them and allow repeats. A set throws repeats away and has no positions, so indexing fails. A dictionary keeps insertion order, but a repeated key just overwrites the earlier one:
orders = ["latte", "bagel", "latte", "muffin"]
print(list(set(orders)) == orders, sorted(set(orders)))
states = {"TX", "CO"}
try:
states[0]
except TypeError as e:
print("set:", e)
menu = {"latte": 5.25, "bagel": 3.25, "latte": 5.50}
print(menu)
Output:
False ['bagel', 'latte', 'muffin']
set: 'set' object is not subscriptable
{'latte': 5.5, 'bagel': 3.25}
The second "latte" key won, so you get 5.5. Dictionaries keep insertion order (Python 3.7+); sets don’t.
That makes set() a quick way to dedupe when order doesn’t matter. When it does, see removing duplicates from a list in Python.
Why can a tuple be a dictionary key but a list can’t?
Dictionary keys and set items must be hashable. A hashable object has a hash value that never changes, so Python can find it fast. Tuples of fixed values qualify; lists don’t, because they can change:
distance = {("Austin", "Dallas"): 195, ("Denver", "Boston"): 1970}
print(distance[("Austin", "Dallas")])
try:
bad = {["Austin", "Dallas"]: 195}
except TypeError as e:
print("list as key:", e)
try:
nested = {[1, 2], [3, 4]}
except TypeError as e:
print("list in set:", e)
Output:
195
list as key: unhashable type: 'list'
list in set: unhashable type: 'list'

TypeError: unhashable type: 'list' as a key or a set item.So use a tuple for compound keys like city pairs or coordinates. For a deeper look at key lookups, read the difference between a list and a dictionary in Python.
Membership speed: list vs set vs dictionary
Checking x in collection scans a list or tuple item by item. A set or dictionary uses a hash table and jumps straight to the answer. I timed 1,000 lookups of the last item in 100,000:
import sys
import timeit
n = 100_000
as_list = list(range(n))
as_tuple = tuple(as_list)
as_set = set(as_list)
as_dict = dict.fromkeys(as_list)
for name, box in [("list", as_list), ("tuple", as_tuple), ("set", as_set), ("dict", as_dict)]:
t = timeit.timeit(lambda: n - 1 in box, number=1_000)
print(f"{name:<6} 1,000 lookups: {t * 1000:9.3f} ms size: {sys.getsizeof(box):>9,} bytes")
Output:
list 1,000 lookups: 450.273 ms size: 800,056 bytes
tuple 1,000 lookups: 525.369 ms size: 800,040 bytes
set 1,000 lookups: 0.064 ms size: 4,194,520 bytes
dict 1,000 lookups: 0.069 ms size: 5,242,960 bytes

Your timings won’t match mine, but the gap will. The catch is memory: you pay for that speed with bigger objects.
Converting between list, tuple, set and dictionary
Each constructor accepts the others, so converting takes one call. dict.fromkeys() also removes duplicates while keeping order:
orders = ["latte", "bagel", "latte", "muffin", "bagel"]
print(set(orders) == {"latte", "bagel", "muffin"})
print(list(dict.fromkeys(orders))) # dedupe, keep first-seen order
items = ["latte", "bagel"]
costs = [5.25, 3.25]
menu = dict(zip(items, costs))
print(menu)
print(list(menu.items()))
Output:
True
['latte', 'bagel', 'muffin']
{'latte': 5.25, 'bagel': 3.25}
[('latte', 5.25), ('bagel', 3.25)]
Turning a set back into an ordered list has its own wrinkles, covered in converting a set to a list in Python. To loop over keys, values or pairs, see iterating through a dictionary in Python.
When to use a list, tuple, set or dictionary
- List: an ordered sequence you’ll edit, like a shopping cart.
- Tuple: a fixed record, like coordinates or a compound key.
- Set: unique items and fast
inchecks, like visited states. - Dictionary: looking things up by name, like prices by menu item.
When in doubt, I start with a list and switch once I need uniqueness or lookups by key.
Each type has a dedicated guide too, so pick the one you’re working with:
- Create an empty set in Python
- Add items to a set in Python
- Update a dictionary in Python
- Work with a tuple of tuples in Python
Frequently asked questions
What is the main difference between a list, tuple, set and dictionary in Python?
A list is ordered and changeable, a tuple is ordered and fixed, a set holds unique unordered items, and a dictionary stores key-value pairs.
Which is faster, a list or a set?
For in checks on large data, a set is much faster because it uses hashing.
Are Python dictionaries ordered?
Yes. Since Python 3.7, dictionaries keep keys in insertion order. Sets don’t keep any order.
Can a set contain a list?
No. Set items must be hashable, and a list raises TypeError: unhashable type: 'list'. Use a tuple instead.
Why use a tuple instead of a list?
When the data shouldn’t change, or you need a dictionary key.
Where are Python’s built-in data structures documented?
See Data Structures 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