How to choose between tuples and lists in Python
The problem
When I started learning Python, I kept seeing tuples everywhere. They looked just like lists but with parentheses instead of brackets. I thought, “Why do I need tuples when I have lists?”
my_list = [1, 2, 3]my_tuple = (1, 2, 3)I just used lists for everything. Then I hit a wall when I tried to use a list as a dictionary key:
# What I triedcache = {}position = [10, 20]cache[position] = "player_location"I got this error:
TypeError: unhashable type: 'list'I didn’t understand why this failed. A list is just a collection of values, right? Why can’t I use it as a key?
What happened?
I was building a simple game and wanted to cache locations. Each position had coordinates like [x, y]. I thought lists were the obvious choice since they’re the default sequence type in Python.
I tried to work around it by converting the list to a string:
cache[str(position)] = "player_location" # Works but feels hackyThis worked, but it felt wrong. Why should I need to convert coordinates to a string?
Then I read about tuples. I changed my code to use tuples instead:
position = (10, 20)cache[position] = "player_location" # Just worksNow it worked without any conversion. But I still didn’t understand WHY tuples could be keys but lists couldn’t. What’s the actual difference?
The reason
I think the key difference comes down to one word: immutability.
Tuples can’t change after you create them. Lists can. This single difference affects everything:
┌────────────────┐│ Lists │ Can add, remove, modify items└────────────────┘ Mutable = can change │ │ Try to use as dict key ▼ ┌─────────┐ │ ERROR │ "unhashable type: 'list'" └─────────┘ Why? If list changes, the hash changes Dictionary can't find it anymore
┌────────────────┐│ Tuples │ Cannot change after creation└────────────────┘ Immutable = can't change │ │ Use as dict key ▼ ┌─────────┐ │ WORKS │ Hash stays the same forever └─────────┘ Dictionary can always find itWhen you use something as a dictionary key, Python calculates a hash value from it. This hash tells Python where to store the value. If the key changes, the hash changes, and Python can’t find the value anymore.
Since lists can change, they can’t be dictionary keys. Since tuples can’t change, they can.
How this affects code design
Once I understood this, I realized tuples aren’t just “lists with parentheses.” They serve a different purpose.
When I use tuples
For dictionary keys
# Cache function results by parametersmemo = {}def fib(n): if n in memo: return memo[n] result = fib(n-1) + fib(n-2) memo[n] = result # n is hashable return result
# Multi-key cachecache = {}cache[(10, 20)] = "player_at_10_20"cache[(10, 30)] = "player_at_10_30"For constant data
# RGB color that shouldn't changeWHITE = (255, 255, 255)
# Screen resolutionSCREEN_SIZE = (1920, 1080)
# Geographic coordinatesNEW_YORK = (40.7128, -74.0060)For function default arguments
This one surprised me. I used to write:
# WRONG - mutable default argumentdef add_item(item, items=[]): items.append(item) return itemsThis bug is subtle. The list is created once when Python defines the function, not every time you call it. So multiple calls share the same list:
>>> add_item("a")['a']>>> add_item("b")['a', 'b'] # Wait, where did 'a' come from?The fix is to use a tuple as the default:
# CORRECT - immutable default argumentdef add_item(item, items=()): return list(items) + [item]Now each call gets a fresh list.
To signal intent
When I return a tuple from a function, I’m saying “these values have a fixed relationship.”
# Tuple says: always returns width and heightdef get_screen_size(): return (1920, 1080)
# List says: here's a collection of itemsdef get_files(): return ["file1.txt", "file2.txt", "file3.png"]When I use lists
For data that changes
shopping_list = ["milk", "eggs"]shopping_list.append("bread") # Lists have .append()shopping_list.remove("eggs") # and .remove()When I need list methods
Tuples don’t have methods like .append(), .extend(), .remove(), .sort(). If I need these, I use a list.
numbers = [3, 1, 4, 1, 5]numbers.sort() # Tuples can't do thisnumbers.append(9) # Or thisnumbers.extend([2, 6]) # Or thisFor building collections incrementally
results = []for item in large_dataset: processed = process(item) results.append(processed) # Tuples can't growPerformance differences
I was curious about performance, so I tested it:
import sys
my_list = [1, 2, 3, 4, 5]my_tuple = (1, 2, 3, 4, 5)
print(f"List: {sys.getsizeof(my_list)} bytes")print(f"Tuple: {sys.getsizeof(my_tuple)} bytes")Output:
List: 104 bytesTuple: 88 bytesThe tuple uses less memory. Why?
Lists overallocate space. They reserve extra room for future items so they don’t need to resize every time you append something. Tuples don’t need this overhead because they can’t grow.
In practice, I don’t worry about this unless I’m working with millions of items. The memory difference is usually negligible. But it’s good to know.
When the choice doesn’t matter
Sometimes it doesn’t matter which you use. If you’re just passing data around and don’t need mutability or hashability, either works.
I default to lists unless I have a specific reason to use tuples. Lists are more flexible and most Python code expects lists. But when I need immutability or dictionary keys, tuples are the right tool.
Summary
In this post, I showed why tuples exist alongside lists in Python. The key point is that tuples provide immutability, which makes them hashable and safe to use as dictionary keys. Use lists for mutable data that changes, and use tuples for constant data, dictionary keys, and to signal intent to other developers.
The choice isn’t just technical—it communicates your design decisions. When I use a tuple, I’m saying “this data should never change.” When I use a list, I’m saying “this data might change.”
Final Words + More Resources
My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
- 👨💻 Python documentation on sequence types
- 👨💻 Why are tuples immutable?
- 👨💻 Python tuples vs lists performance
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!
Comments