Lesson 5 / 25
Tuples, namedtuple and dataclasses
Choose between tuples, named tuples and dataclasses for records.
Fixed-shape records
A tuple is an immutable sequence. Because it cannot change, a tuple of hashable values is itself hashable, so it can be a dictionary key or a set member (for example, (row, col) coordinates). Tuples are slightly smaller and faster to create than lists, support unpacking (name, score = pair) and are the natural return type for multiple values. For readable records, collections.namedtuple or typing.NamedTuple adds field names while staying a tuple (immutable, indexable, lightweight). dataclasses.dataclass generates __init__, __repr__ and __eq__ for regular classes; options include frozen=True (immutable and hashable), order=True (comparison methods), slots=True (Python 3.10+, less memory and faster attribute access) and field(default_factory=list) for mutable defaults. Use tuples for small, fixed groupings and keys, named tuples for lightweight immutable records, and dataclasses when you want methods, defaults, type hints and optional mutability. Libraries such as attrs and Pydantic (with validation) offer more features.
Records three ways
Tuples as keys, NamedTuple and a slotted dataclass.
from dataclasses import dataclass, field
from typing import NamedTuple
# tuple as a dictionary key
seat_prices = {(1, "A"): 1200, (1, "B"): 1200, (10, "C"): 800}
print(seat_prices[(1, "A")]) # 1200
class Point(NamedTuple):
lat: float
lng: float
pune = Point(18.52, 73.86)
lat, lng = pune # still a tuple: unpacks
print(pune.lat, pune[1]) # 18.52 73.86
@dataclass(slots=True)
class Order:
order_id: str
city: str
items: list[str] = field(default_factory=list) # safe mutable default
paid: bool = False
def add(self, sku: str) -> None:
self.items.append(sku)
@dataclass(frozen=True, order=True)
class Version:
major: int
minor: int
o = Order("o-1", "Pune")
o.add("pen")
print(o) # Order(order_id='o-1', city='Pune', items=['pen'], paid=False)
print(sorted([Version(1, 10), Version(1, 2)])) # [Version(major=1, minor=2), Version(major=1, minor=10)]
print({Version(2, 0): "current"}) # frozen dataclasses are hashableA printed form versus a notebook
A tuple is a printed form: fixed fields that cannot be changed once filled in, which makes it safe to file under an index (a dict key). A dataclass is a notebook template with labelled pages that you can keep editing.
Quick check: Why can a tuple of strings be used as a dictionary key while a list cannot?
- Tuples are faster
- Tuples are immutable and hashable; lists are mutable and unhashable
- Lists cannot hold strings
- Dictionaries only accept tuples
Answer
Tuples are immutable and hashable; lists are mutable and unhashable — Keys must be hashable, and their hash must not change.