Python Basics — Named Tuples

3 minute read

Named Tuples

Named tuples give meaning to each position in a tuple. Instead of accessing elements by index, you access them by name — making your code more readable.

collections.namedtuple

from collections import namedtuple

# Define a named tuple type
Point = namedtuple("Point", ["x", "y"])

# Create instances
p = Point(10, 20)
print(p.x)   # 10
print(p.y)   # 20
print(p)     # Point(x=10, y=20)

Different Ways to Define Fields

from collections import namedtuple

# List of strings
Point = namedtuple("Point", ["x", "y"])

# Space-separated string
Point = namedtuple("Point", "x y")

# Comma-separated string
Point = namedtuple("Point", "x, y")

All three produce the same result.

typing.NamedTuple (Modern Style)

Python 3.6+ introduced a class-based syntax with type hints:

from typing import NamedTuple

class Point(NamedTuple):
    x: float
    y: float

p = Point(10.5, 20.3)
print(p.x)    # 10.5
print(p.y)    # 20.3
print(p)      # Point(x=10.5, y=20.3)

With Default Values

from typing import NamedTuple

class Color(NamedTuple):
    red: int
    green: int
    blue: int
    alpha: float = 1.0  # default value

c1 = Color(255, 128, 0)
print(c1)  # Color(red=255, green=128, blue=0, alpha=1.0)

c2 = Color(255, 128, 0, 0.5)
print(c2)  # Color(red=255, green=128, blue=0, alpha=0.5)

Accessing by Name vs Index

Named tuples work both ways:

from collections import namedtuple

Student = namedtuple("Student", ["name", "age", "grade"])
s = Student("Alice", 20, "A")

# By name (preferred)
print(s.name)   # Alice
print(s.grade)  # A

# By index (still works)
print(s[0])     # Alice
print(s[2])     # A

# Unpacking
name, age, grade = s
print(name, age, grade)  # Alice 20 A

Useful Methods

_asdict() — Convert to Dictionary

from collections import namedtuple

Point = namedtuple("Point", "x y")
p = Point(10, 20)

d = p._asdict()
print(d)  # {'x': 10, 'y': 20}

_replace() — Create Modified Copy

Named tuples are immutable, but _replace() creates a new instance with changes:

from collections import namedtuple

Point = namedtuple("Point", "x y")
p1 = Point(10, 20)
p2 = p1._replace(x=99)

print(p1)  # Point(x=10, y=20)  (unchanged)
print(p2)  # Point(x=99, y=20)  (new tuple)

_fields — Get Field Names

from collections import namedtuple

Car = namedtuple("Car", "make model year")
print(Car._fields)  # ('make', 'model', 'year')

_make() — Create from Iterable

from collections import namedtuple

Point = namedtuple("Point", "x y")
data = [10, 20]
p = Point._make(data)
print(p)  # Point(x=10, y=20)

Real-World Examples

CSV Records

from collections import namedtuple

Employee = namedtuple("Employee", "id name department salary")

# Simulating CSV rows
rows = [
    (1, "Alice", "Engineering", 95000),
    (2, "Bob", "Marketing", 85000),
    (3, "Charlie", "Engineering", 92000),
]

employees = [Employee._make(row) for row in rows]

for emp in employees:
    if emp.department == "Engineering":
        print(f"{emp.name}: ${emp.salary:,}")
# Alice: $95,000
# Charlie: $92,000

Database Results

from typing import NamedTuple

class DBRow(NamedTuple):
    id: int
    username: str
    email: str
    active: bool

row = DBRow(1, "alice", "alice@example.com", True)
print(f"User {row.username} ({'active' if row.active else 'inactive'})")
# User alice (active)

When to Use Named Tuples

Use Named Tuple When… Use Something Else When…
Data is immutable Data needs to change → use dataclass
Few fields, no methods Need methods → use class
Simple records Complex behavior → use class
Dictionary keys needed Mutable required → use list/dict
Tuple already works Need inheritance → use class

Named Tuple vs dataclass (Preview)

from typing import NamedTuple
from dataclasses import dataclass

# Named tuple — immutable
class PointNT(NamedTuple):
    x: float
    y: float

# Dataclass — mutable by default
@dataclass
class PointDC:
    x: float
    y: float

nt = PointNT(1, 2)
dc = PointDC(1, 2)

# nt.x = 99  # ❌ AttributeError
dc.x = 99    # ✅ Works

Summary

  • namedtuple("Name", fields) creates a tuple with named fields
  • typing.NamedTuple (class syntax) adds type hints and defaults
  • Access by name (p.x) or index (p[0])
  • _asdict() → dict, _replace() → modified copy, _fields → names
  • Named tuples are immutable, hashable, and lightweight
  • Use for simple, read-only records — upgrade to dataclass for mutable data

Next up: Tuples vs Lists →

Updated: