Quick Answer

A Python list is mutable, so you can add, remove, and change items after creating it. Use a list for data that grows or changes. A tuple is immutable, so once created it cannot change. That makes it a bit faster, lighter in memory, and hashable, so it can be a dictionary key or set member. Rule of thumb: use a list when the collection will change, and a tuple when the data is fixed or you need it as a key.

Python List vs Tuple in a Nutshell

If you are learning Python, the python list vs tuple question comes up fast, and the good news is the core idea is simple: a list can change, a tuple cannot. Almost everything else, from speed to where you can use each one, flows from that single difference.

Both are ordered collections. Both can hold any type of value, keep duplicates, and let you read items by position (indexing). You write a list with square brackets and a tuple with parentheses:

fruits_list = ["apple", "banana", "cherry"]   # list
fruits_tuple = ("apple", "banana", "cherry")  # tuple

print(fruits_list[0])   # apple
print(fruits_tuple[0])  # apple

They look almost identical, but the moment you try to modify them they behave very differently. Let's break down what that means and how to choose. Brand new to the language? Our free Python course walks through these building blocks step by step.

Side-by-Side Comparison

Here is the whole story at a glance before we dig into each row.

FeatureListTuple
Mutable (can change)YesNo
Syntax[1, 2, 3](1, 2, 3)
Usable as a dict key / set memberNoOnly if all items are immutable
Built-in methods11 (append, sort, pop, ...)2 (count, index)
Memory usedMoreLess
Creation speed (literals)SlowerFaster
Best forData that changesFixed data / keys

Every one of these rows traces back to mutability, so that's where we start.

Mutability: The Core Difference

Mutability is the one thing to truly understand; the rest are consequences. A list lets you add, replace, and delete items in place:

scores = [90, 85, 70]
scores.append(60)      # add
scores[0] = 95         # replace
scores.remove(70)      # delete
print(scores)          # [95, 85, 60]

A tuple refuses all of that. Once it exists, it is frozen:

point = (3, 4)
point[0] = 5
# TypeError: 'tuple' object does not support item assignment

This is not Python being difficult, immutability is a feature. When you pass a tuple around, you know for certain that no other part of your program can quietly change it behind your back. That guarantee is exactly why some data belongs in a tuple, and it is also what makes the next feature possible.

Hashability: Why Tuples Can Be Dict Keys

Here is the most practical reason to care about the difference. Python dictionaries and sets need their keys to be hashable, meaning Python must be able to compute a stable number (a hash) for the value. That only works if the value cannot change. Because tuples are immutable they are hashable; because lists are not, they are not.

>>> hash((1, 2, 3))
529344067295497451
>>> hash([1, 2, 3])
TypeError: unhashable type: 'list'

This makes tuples perfect as compound keys. Say you want to store values on a grid using a (row, column) pair:

grid = {}
grid[(0, 0)] = "start"
grid[(2, 3)] = "treasure"
print(grid[(2, 3)])   # treasure

Try the same with a list as the key and you get a TypeError. So if you need a collection to act as a dictionary key or to live inside a set, it has to be a tuple.

Performance and Memory

Tuples are lighter and, for fixed data, faster to create. You can see the memory gap yourself with sys.getsizeof (numbers shown are for 64-bit CPython and may vary slightly by version):

import sys
print(sys.getsizeof([1, 2, 3, 4, 5]))  # 104
print(sys.getsizeof((1, 2, 3, 4, 5)))  # 80

Why the difference? A list keeps spare capacity so it can grow cheaply when you append. A tuple never grows, so it allocates exactly what it needs and wastes nothing.

Creation speed tells a similar story. A tuple written as a literal like (1, 2, 3) is stored by Python as a single ready-made constant, while a list literal is rebuilt every time that line runs. In a tight loop, constant tuples are noticeably quicker to produce.

Be honest about scale, though. For indexing and looping, the two are about the same, and for everyday programs these gaps are tiny. Choose based on whether the data should change, not to chase microseconds.

When to Use a List vs a Tuple

Here is the simple decision guide.

Reach for a list when...

  • The collection will grow or shrink (a to-do list, search results, rows read from a file).
  • You need to sort, reverse, or edit items in place.
  • The items are all the same kind of thing and you'll loop over them.

Reach for a tuple when...

  • The data is fixed and should not change (an RGB colour, a date as (year, month, day), a latitude/longitude pair).
  • You need it as a dictionary key or inside a set.
  • A function returns several values at once, since return name, age hands back a tuple.
  • You want to protect data from accidental edits.

A very common pattern combines both: use a tuple for a single record (one person's fixed details) and a list of tuples when you have many records you might add to.

people = [
    ("Aarav", 21),
    ("Diya", 22),
]
people.append(("Rohan", 20))   # list grows, each record stays a tuple

Named Tuples: Tuples With Labels

A plain tuple has one weakness: person[0] and person[1] don't tell you what they mean. A named tuple fixes that by giving each position a label, while staying a real, immutable tuple.

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])
p = Point(3, 4)

print(p.x)        # 3  (read by name)
print(p[0])       # 3  (still works by index)
print(p)          # Point(x=3, y=4)

You get readable, self-documenting code without giving up any tuple benefits, since it is still hashable and still immutable. Named tuples are a great middle ground when a tuple's data has clear fields but you don't need a full class.

Common Gotchas

1. A one-item tuple needs a trailing comma

This trips up almost everyone. Parentheses alone don't make a tuple, the comma does.

a = (5)     # just the number 5, in brackets
b = (5,)    # a tuple with one item
print(type(a).__name__)   # int
print(type(b).__name__)   # tuple

2. Tuple immutability is only skin-deep

A tuple cannot swap out its own items, but if an item is itself mutable (like a list), that inner object can still change:

data = (1, [2, 3])
data[1].append(4)
print(data)        # (1, [2, 3, 4])

And because it now contains a mutable list, that tuple is no longer hashable, so you cannot use it as a dictionary key. If you need a truly frozen, hashable tuple, keep only immutable items inside it.

Frequently Asked Questions

Is a tuple faster than a list in Python?

For fixed data, yes. A constant tuple literal is stored as a single ready-made object, so it is created faster than an equivalent list, and it uses less memory. But for indexing and looping the speeds are almost identical, so choose a tuple for correctness (immutable data) rather than for a small speed gain.

Can I use a list as a dictionary key?

No. Dictionary keys must be hashable, and because lists are mutable they are unhashable, so it raises TypeError: unhashable type: 'list'. Use a tuple instead, as long as every item inside the tuple is also immutable.

How do I create a tuple with only one element?

Add a trailing comma: (5,) is a one-item tuple, but (5) is just the integer 5. The comma, not the parentheses, is what makes a tuple. You can even write x = 5, with no brackets at all.

Can a tuple be changed after it is created?

No. You cannot add, remove, or replace its items, and trying to raises a TypeError. The one exception is that if a tuple holds a mutable object such as a list, that inner object can still be modified, but the tuple's own structure stays fixed.

When should I use a named tuple?

Use a named tuple when your data has fixed, clearly-named fields, like a point with x and y, or a colour with red, green, and blue values. You get readable access by name while keeping every benefit of a normal tuple (immutable and hashable), without writing a full class.