Technology  /  Python

๐Ÿ Python 78 guides ยท updated 2026

From first variable to OOP, generators, and real projects โ€” the language that runs everything from data pipelines to AI agents, taught the practical way.

Python Tuples in Depth: Packing, Unpacking, and Why Immutability Matters

Tuples and lists look almost identical, so programmers often use them interchangeably. They are not interchangeable. Tuples communicate something a list does not: โ€œthis collection has a fixed structure and should not change.โ€ That signal matters for code readability and for Pythonโ€™s runtime.

Creating Tuples

# Parentheses optional for plain packing
coordinates = (10, 20)
color = 255, 128, 0 # also a tuple
# Single-element tuple โ€” the trailing comma is required
single = (42,)
not_a_tuple = (42) # this is just the integer 42
print(type(single)) # <class 'tuple'>
print(type(not_a_tuple)) # <class 'int'>
# Empty tuple
empty = ()
empty2 = tuple()
# From an iterable
t = tuple(range(5))
print(t) # (0, 1, 2, 3, 4)

Tuple Packing and Unpacking

Packing: assigning multiple values to a single tuple variable.

# Pack a record
person = "Alice", 30, "engineer"
print(person) # ('Alice', 30, 'engineer')

Unpacking: extracting tuple values into separate variables in one assignment.

name, age, role = person
print(name, age, role) # Alice 30 engineer
# Swap two variables without a temp variable
a, b = 10, 20
a, b = b, a
print(a, b) # 20 10 โ€” classic tuple swap
# Return multiple values from a function
def min_max(numbers):
return min(numbers), max(numbers) # returns a tuple
low, high = min_max([5, 2, 9, 1, 7])
print(low, high) # 1 9

Extended Unpacking with *

The * operator in unpacking captures โ€œthe restโ€ into a list:

first, *middle, last = (1, 2, 3, 4, 5)
print(first) # 1
print(middle) # [2, 3, 4] โ€” note: a list, not a tuple
print(last) # 5
# Skip middle values
head, *_ = (10, 20, 30, 40)
print(head) # 10
# First and last, ignore middle
start, *_, end = range(10)
print(start, end) # 0 9

This is called โ€œstarred assignmentโ€ or โ€œextended unpackingโ€ and only works in Python 3.

Tuples as Dictionary Keys

Because tuples are hashable (provided their elements are hashable), they work as dictionary keys where lists cannot:

# Grid coordinates as dict keys
grid = {}
grid[(0, 0)] = "start"
grid[(1, 2)] = "waypoint"
grid[(5, 5)] = "end"
print(grid[(1, 2)]) # "waypoint"
# Compound key example
visits = {}
def record_visit(user_id, page):
key = (user_id, page)
visits[key] = visits.get(key, 0) + 1
record_visit("alice", "/home")
record_visit("alice", "/about")
record_visit("alice", "/home")
print(visits) # {('alice', '/home'): 2, ('alice', '/about'): 1}

Tuples in Sets

Same reason: tuples are hashable, lists are not.

seen_positions = set()
seen_positions.add((0, 0))
seen_positions.add((1, 2))
seen_positions.add((0, 0)) # duplicate โ€” ignored by set
print(seen_positions) # {(0, 0), (1, 2)}

Performance: Tuples vs Lists

Tuples are slightly faster than lists for iteration and creation, and use slightly less memory. For a fixed-size collection that never changes, a tuple is the right type.

import sys
import timeit
# Memory comparison
t = (1, 2, 3, 4, 5)
l = [1, 2, 3, 4, 5]
print(sys.getsizeof(t)) # typically 80 bytes
print(sys.getsizeof(l)) # typically 104 bytes
# Creation speed (tuples are faster for literals)
tuple_time = timeit.timeit("(1, 2, 3, 4, 5)", number=10_000_000)
list_time = timeit.timeit("[1, 2, 3, 4, 5]", number=10_000_000)
print(f"Tuple: {tuple_time:.3f}s, List: {list_time:.3f}s")

Named Access with namedtuple

When you find yourself writing record[0], record[1], record[2] across your codebase, that is a signal to use namedtuple:

from collections import namedtuple
# Before: plain tuple โ€” position tells you nothing
city_data = ("London", 8_982_000, 51.5074)
print(city_data[1]) # 8982000 โ€” what is this field again?
# After: namedtuple โ€” intention is clear
City = namedtuple('City', ['name', 'population', 'latitude'])
london = City("London", 8_982_000, 51.5074)
print(london.population) # 8982000 โ€” obvious

When to Use Tuple vs List

Use a tuple when:

Use a list when: