PythonMastery
beginner 12 min read · lesson 12 of 19 in Python Fundamentals

Tuples: Lists That Can't Be Changed

1 · The lesson

read

A tuple is an ordered sequence, like a list. It has the same indexing (t[0]), the same slicing (t[1:3]) and the same iteration (for x in t:). But once you create a tuple, it can never be modified: you can't add, remove or replace its items.

That sounds like a limitation, and sometimes it is. But it is also the reason a tuple can be a dictionary key. Tuples are also how a function returns several values at once. You will use both of these all the time.


1. Creating Tuples

You create a tuple with parentheses instead of square brackets:

python
# 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 tuple with one element MUST have a comma
not_a_tuple = (42)                 # this is just an int in parentheses
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 leave the parentheses out. It's the commas that make a tuple:

python
point = 3, 4                       # also a tuple
print(point)                       # (3, 4)
print(type(point))                 # <class 'tuple'>

2. Reading from Tuples (Same as Lists)

Indexing, slicing and len() work exactly as they do on lists:

python
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. Anything that would change a list in place raises an error on a tuple:

python
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)

+ creates a new tuple, and the original tuple does not change. * (repetition) also creates a new tuple.


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. Nobody should append a third number to the coordinate (3, 4), or edit the date (2026, 5, 14) in place. A tuple tells the next person who reads your code: these values are one unit, do not change them.

b) You want to use it as a dictionary key. A list can't be a dict key, because a list can change, and then its hash would change too. A tuple can be a key:

python
# 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) A function returning several values. In real code, this is the reason you will see most often:

python
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

The line name, age, email = get_user() is called tuple unpacking. You will write lines like it all the time.


5. Tuple Unpacking

You can assign multiple variables from a single tuple in one line:

python
# 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, with no temporary variable needed!
a = 10
b = 20
a, b = b, a                        # this works by tuple unpacking
print(a, b)                        # 20 10

# Star unpacking: collect "the rest" into a list
first, *middle, last = (1, 2, 3, 4, 5)
print(first)                       # 1
print(middle)                      # [2, 3, 4]
print(last)                        # 5

In C or Java, swapping two variables takes three lines and a temporary variable. In Python, a, b = b, a does it in one.


6. Tuples vs Lists: Quick Reference

FeatureList [1, 2, 3]Tuple (1, 2, 3)
Mutable?Yes (can change)No (frozen)
SyntaxSquare bracketsParentheses (or commas)
Can be dict keyNoYes
Slightly faster?NoYes (small win)
Common useCollections that grow/shrinkFixed records, multi-return, coordinates
MethodsMany (append, pop, sort, …)Just two (count, index)

Rule of thumb: if the collection will grow, shrink or change, use a list. If the values belong together as one record, use a tuple.


7. Mistakes You'll Hit

1. Forgetting the comma on a single-element tuple

python
x = (5)                            # this is just the integer 5
x = (5,)                           # this is a tuple with one element

2. Trying to modify a tuple

python
# 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. A comma you didn't mean makes a tuple

python
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. That's 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.

python
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.

This exercise uses def, which you will learn in the next lesson, Functions & Scoping. For now, copy the skeleton as it is and fill in the lines marked TODO.

Skeleton:

python
def summarise(numbers):
    # TODO 1: return None if the list is empty
    # TODO 2: build the tuple (min, max, average), with the 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. This is useful: Python reports the mistake on that line, instead of passing a wrong value on to the rest of your program.
Show full solution
python
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 does the job a small class would do in other languages: it groups three
values that belong together. Because it's immutable, the caller can't change the
result by accident and confuse later code. Python's own divmod() and
str.partition() return tuples for the same reason, and looping over
dict.items() hands you one (key, value) tuple at a time.


What You Learned

  • Tuples are immutable ordered sequences: you read them with the same syntax as lists, but you can't add, remove or replace items.
  • Create with parentheses or just commas: (3, 4) or 3, 4.
  • A one-element tuple needs a trailing comma: (42,).
  • Use tuples for fixed records, dict keys, and multi-return values.
  • Tuple unpacking assigns several variables in one line, and swaps two without a temporary variable.

You will create fewer tuples than lists, but you will use them more often than you might think: every function that returns more than one value is returning a tuple.

Next: Functions & Scoping.


Source: adapted from Python official documentation Section 5.3 (Tuples and Sequences). PSF License.

Practice this

on practicepython.in

Short exercises that run in your browser and tell you what your code did, as well as whether a test passed.

Found this useful? Share it with a friend who’s learning Python.