A list and a tuple both hold an ordered collection of items that you index from 0. The one difference that matters — a list can be changed after it is made; a tuple cannot — explains every other difference in the table.
The comparison table
| Feature | List | Tuple |
|---|---|---|
| Mutability | Mutable | Immutable |
| Syntax | [1, 2, 3] | (1, 2, 3) — the comma makes the tuple, the brackets are optional |
| Single element | [5] | (5,) — trailing comma required |
| Methods | Many: append, insert, remove, pop, sort, reverse, extend … | Two: count, index |
| Speed | Slightly slower to create and iterate | Slightly faster |
| Memory | More (room to grow) | Less (fixed size) |
| As dictionary key | Not allowed (unhashable) | Allowed, if its items are immutable |
| Typical use | A collection that changes: marks entered one by one, a queue of tasks | A fixed record: a coordinate (x, y), an RGB colour, a date (d, m, y) |
Mutability, shown
marks = [72, 85, 90]
marks[0] = 75 # fine
marks.append(64) # fine
print(marks) # [75, 85, 90, 64]
point = (3, 4)
point[0] = 5 # TypeError: 'tuple' object does not support item assignment
You can build a new tuple from an old one — point = point + (0,) — but that creates a fresh object; the original never changed.
The trailing-comma trap
t = (5) # this is an int
u = (5,) # this is a tuple with one element
print(type(t), type(u)) # <class 'int'> <class 'tuple'>
Board papers love this line. The bracket is not what makes a tuple; the comma is. a = 1, 2 is also a tuple.
Packing, unpacking and swapping
Tuples make several everyday idioms clean:
p = 10, 20 # packing
x, y = p # unpacking
a, b = b, a # swap without a temporary variable
for i, name in enumerate(["Asha", "Ravi"]): # enumerate yields tuples
print(i, name)
Functions that "return two values" are returning one tuple: return q, r.
Which to use
- The data will change → list.
- The data is a fixed record and should not be accidentally modified → tuple.
- You need it as a dictionary key or a set element → tuple (lists cannot be hashed).
- You want to signal intent to the reader:
(lat, lon)says "these two belong together and stay put".
A subtle one: mutable inside immutable
t = ([1, 2], "x")
t[0].append(3) # allowed — the list inside changed, the tuple did not
print(t) # ([1, 2, 3], 'x')
The tuple holds a reference to the list; that reference cannot be replaced, but the list it points to is still a list.
How it is tested
- "Write two differences between a list and a tuple." — Mutability and syntax, in a table.
- "What is the output?" with
(5)vs(5,), or witht[0] = …on a tuple (expect the error). - "Convert a list to a tuple and back." —
tuple([1, 2])andlist((1, 2)). - "Why can a tuple be a dictionary key but a list cannot?" — Keys must be hashable; hashable means immutable; a list can change so its hash could change.