Tuples: Lists That Can't Be Changed
1 · The lesson
readA tuple is Python's other ordered sequence type. You can think of it as a read-only list — same indexing, same slicing, same iteration, but once you create one, it can never be modified.
That sounds restrictive, but it's actually a superpower. Tuples are faster, safer, and unlock patterns lists can't.
1. Creating Tuples
You create a tuple with parentheses instead of square brackets:
# A tuple of coordinates point = (3, 4) print(point) # (3, 4) print(type(point)) # <class 'tuple'> # Multiple types are fine, same as lists person = ("Alice", 30, True) print(person) # ('Alice', 30, True) # An empty tuple empty = () print(len(empty)) # 0 # A single-element tuple — the comma is REQUIRED not_a_tuple = (42) # this is just an int in parens real_tuple = (42,) # this is a tuple print(type(not_a_tuple)) # <class 'int'> print(type(real_tuple)) # <class 'tuple'>
That trailing comma for single-element tuples is the most common tuple gotcha. Remember it.
You can even skip the parentheses entirely — Python recognizes a tuple from the commas alone:
point = 3, 4 # also a tuple print(point) # (3, 4) print(type(point)) # <class 'tuple'>
2. Reading from Tuples (Same as Lists)
Indexing, slicing, length — all identical to lists:
person = ("Alice", 30, "Engineer") print(person[0]) # Alice print(person[-1]) # Engineer print(person[0:2]) # ('Alice', 30) print(len(person)) # 3 # Iteration works too for item in person: print(item)
3. What You CAN'T Do
Tuples are immutable — every operation that would change a list raises an error on a tuple:
point = (3, 4) # All of these would crash: # point[0] = 5 # TypeError: 'tuple' object does not support item assignment # point.append(7) # AttributeError: 'tuple' object has no attribute 'append' # del point[0] # TypeError: 'tuple' object doesn't support item deletion # What you CAN do: create a new tuple new_point = point + (5,) print(new_point) # (3, 4, 5) # Or rebuild from scratch updated = (point[0], 99) print(updated) # (3, 99)
The + operator creates a new tuple — it doesn't modify the original. Same with * for repetition.
4. Why Tuples Exist — When to Use Them
Three real reasons to reach for a tuple instead of a list:
a) The data should never change. A coordinate (3, 4) shouldn't have items appended to it. A date (2026, 5, 14) shouldn't be modified. Tuples signal "this is one unit, don't touch it".
b) You want it as a dictionary key. Lists can't be dict keys (they're mutable, so their hash could change). Tuples can:
# Mapping a 2D grid coordinate to a value board = {} board[(0, 0)] = "X" board[(1, 2)] = "O" print(board) # {(0, 0): 'X', (1, 2): 'O'}
c) Functions returning multiple values. This is the most common reason in real code:
def get_user(): # Returning "multiple values" actually means returning a tuple return "Alice", 30, "alice@example.com" name, age, email = get_user() print(name) # Alice print(age) # 30 print(email) # alice@example.com
That last pattern is called tuple unpacking, and it's everywhere in Python.
5. Tuple Unpacking — The Superpower
You can assign multiple variables from a single tuple in one line:
# Basic unpacking point = (3, 4) x, y = point print(x, y) # 3 4 # Works in for-loops too pairs = [(1, "one"), (2, "two"), (3, "three")] for number, word in pairs: print(f"{number} is {word}") # Swap two variables — no temp needed! a = 10 b = 20 a, b = b, a # uses tuple unpacking under the hood print(a, b) # 20 10 # Star unpacking — grab "the rest" first, *middle, last = (1, 2, 3, 4, 5) print(first) # 1 print(middle) # [2, 3, 4] print(last) # 5
The variable swap (a, b = b, a) is one of those things that makes Python feel magical. Other languages need a temporary variable.
6. Tuples vs Lists — Quick Reference
| Feature | List [1, 2, 3] | Tuple (1, 2, 3) |
|---|---|---|
| Mutable? | Yes (can change) | No (frozen) |
| Syntax | Square brackets | Parentheses (or commas) |
| Can be dict key | No | Yes |
| Slightly faster? | No | Yes (small win) |
| Common use | Collections that grow/shrink | Fixed records, multi-return, coordinates |
| Methods | Many (append, pop, sort, …) | Just two (count, index) |
Rule of thumb: if you're collecting things that will grow or change, use a list. If you're packaging things that belong together as a unit, use a tuple.
7. Mistakes You'll Hit
1. Forgetting the comma on a single-element tuple
x = (5) # this is just the integer 5 x = (5,) # this is a tuple with one element
2. Trying to modify a tuple
# t = (1, 2, 3) # t[0] = 99 # TypeError — tuples are immutable
Fix: create a new tuple, or use a list if you need to mutate.
3. Confusing tuple unpacking with list creation
a = 1, 2, 3 # tuple: a = (1, 2, 3) b = [1, 2, 3] # list
🎯 Your Turn — Return Three Things at Once
A function can only return one object — but that object can be a tuple, which is
how Python functions return several values at once without inventing a class.
Write summarise(numbers) that returns a tuple of (smallest, largest, average),
then unpack it at the call site into three named variables.
summarise([4, 8, 15, 16, 23, 42]) → (4, 42, 18.0) summarise([7]) → (7, 7, 7.0) summarise([-5, 5]) → (-5, 5, 0.0)
Return None for an empty list rather than crashing.
Skeleton:
def summarise(numbers): # TODO 1: return None if the list is empty # TODO 2: build the tuple (min, max, average) — average as a float ... low, high, mean = summarise([4, 8, 15, 16, 23, 42]) print(f"low={low} high={high} mean={mean}") # low=4 high=42 mean=18.0 print(summarise([])) # None
Hint 1 — The parentheses are optional
return smallest, largest, average already builds a tuple; the commas
are what make it one, not the brackets. Writing return (a, b, c) is
the same thing and is often clearer to read.
Hint 2 — Unpacking must match in length
low, high, mean = summarise(...) works because the tuple has exactly
three items. If it had four you would get ValueError: too many values to
unpack. That strictness is a feature — it catches the mistake at the call
site instead of letting a wrong value flow onward.
Show full solution
def summarise(numbers): if not numbers: return None return min(numbers), max(numbers), sum(numbers) / len(numbers) low, high, mean = summarise([4, 8, 15, 16, 23, 42]) print(f"low={low} high={high} mean={mean}") # low=4 high=42 mean=18.0 print(summarise([7])) # (7, 7, 7.0) print(summarise([-5, 5])) # (-5, 5, 0.0) print(summarise([])) # None
The tuple is doing the job a small class would do elsewhere — grouping three
related values that travel together. Because tuples are immutable, the caller
cannot accidentally modify the result and confuse later code, which is exactly
why Python's own functions (divmod, str.partition, dict.items) return them
too.
Recap
- Tuples are immutable ordered sequences — same as lists, but frozen.
- Create with parentheses or just commas:
(3, 4)or3, 4. - A one-element tuple needs a trailing comma:
(42,). - Use tuples for fixed records, dict keys, and multi-return values.
- Tuple unpacking lets you assign multiple variables in one line — and swap variables without a temp.
Tuples are the quieter sibling of lists, but they're everywhere in idiomatic Python. The moment you write a function that returns more than one thing, you're using a tuple — whether you realize it or not.
Source: adapted from Python official documentation Section 5.3 (Tuples and Sequences). PSF License.
Practice this
on practicepython.inShort exercises that run in your browser and tell you what your code actually did, not just whether a test passed.