Lesson 10 — Immutable Sequences

Tuples

Tuples are immutable sequences — they look like lists but cannot be changed after creation. This immutability makes them useful for data that should not change and enables them as dictionary keys.

PYTHON — Tuple basics
# Creation:
point   = (3, 7)
learner = ("Thandi", 21, "Java", 74.5)
single  = (42,)  # IMPORTANT: trailing comma required for single-element!
empty   = ()

# Parentheses are actually optional (comma makes it a tuple):
also_tuple = 1, 2, 3
print(type(also_tuple))  # <class 'tuple'>

# Access — same as list:
print(learner[0])   # Thandi
print(learner[-1])  # 74.5

# Attempting to modify raises TypeError:
try:
    learner[0] = "Sipho"
except TypeError as e:
    print(f"Cannot modify: {e}")  # 'tuple' object does not support item assignment

Tuple Unpacking

Unpacking is one of Python's most elegant features — assign a tuple's values to individual variables in one statement.

PYTHON — Unpacking
# Basic unpacking:
x, y = (3, 7)
print(f"x={x}, y={y}")

# Swap using tuple unpacking:
a, b = 5, 10
a, b = b, a
print(a, b)  # 10 5

# Extended unpacking with *:
first, *middle, last = (10, 20, 30, 40, 50)
print(first)   # 10
print(middle)  # [20, 30, 40]
print(last)    # 50

# Function returning multiple values (returns a tuple):
def min_max(numbers):
    return min(numbers), max(numbers)

low, high = min_max([65, 72, 80, 58, 91])
print(f"Low: {low}, High: {high}")  # Low: 58, High: 91

Named Tuples

PYTHON — Named tuples
from collections import namedtuple

# Create a named tuple class:
Learner = namedtuple("Learner", ["name", "age", "course", "mark"])

# Create instances:
l1 = Learner("Thandi", 21, "Java",   74.5)
l2 = Learner("Sipho",  24, "Python", 81.0)

# Access by name (readable) or index (compatible with tuple):
print(l1.name, l1.mark)   # Thandi 74.5
print(l2[1], l2[2])       # 24 Python

# Still immutable:
try:
    l1.name = "Lerato"
except AttributeError as e:
    print(f"Immutable: {e}")

# Useful for function return values — clearer than bare tuples:
defPoint = namedtuple("Point", ["x", "y"])
center = defPoint(0, 0)
print(center)  # Point(x=0, y=0)

Practice Task

Your Turn

Create a tuple of 5 learner records (each a named tuple with name, city, course, mark). Use unpacking to iterate and print each field. Write a function that takes a list of learner tuples and returns a tuple of (min_mark, max_mark, average_mark). Show that tuples can be dictionary keys but lists cannot.

Common Mistakes

  • Forgetting the trailing comma for single-element tuples: (42) is just 42, not a tuple.
  • Trying to modify a tuple element — use a list if you need mutability.
  • Confusing unpacking count — a, b = (1, 2, 3) raises ValueError (too many values).
  • Named tuples are immutable — use _replace() to create a modified copy.

Professional Tip

Functions that return multiple related values should return a named tuple — it makes the return value self-documenting. min_mark, max_mark, avg = statistics(marks) is clear; a, b, c = statistics(marks) is not.

Mini Quiz

What is required to create a single-element tuple in Python?