Q&A library Python

What is a namedtuple in Python and when should I use one?

Python Intermediate collectionsnamedtupletuples

Short answer

A namedtuple is a lightweight immutable record whose fields have names, so you access them by attribute instead of position. Use it for small fixed records where a full class would be overkill.

The short version

A namedtuple is a tuple whose positions also have names, so you can read point.x instead of point[0]. It is immutable and memory-light, making it ideal for small fixed records where a full class would be more than you need. For anything with behaviour or that needs defaults and type hints, a dataclass is often a better fit.

Defining and using one

from collections import namedtuple

Point = namedtuple("Point", ["x", "y"])

p = Point(1, 2)
print(p.x, p.y)     # 1 2
print(p)            # Point(x=1, y=2)

The named access makes code far more readable than positional indexing, and the automatic repr (Point(x=1, y=2)) is helpful when debugging.

The problem it solves

A plain tuple works but is cryptic, because the meaning of each position is not visible at the point of use.

p = (1, 2)
print(p[0], p[1])   # what are 0 and 1 supposed to be?

Six months later, p[0] gives no clue that it is the x coordinate. namedtuple puts the names in the code, so the intent is clear.

It is still a tuple

A namedtuple is a real tuple, so it unpacks, indexes and iterates like one, which keeps it compatible with code that expects tuples.

x, y = p            # unpacking works
p[0]                # positional access still works

Immutability

Like any tuple, a namedtuple cannot be changed after creation, so it is safe to use as a dictionary key or share without fear of mutation.

p.x = 9             # AttributeError, cannot assign

To make a modified copy, use _replace, which returns a new namedtuple.

p2 = p._replace(x=9)   # Point(x=9, y=2), p unchanged

Useful helpers

_asdict converts to a dictionary, and _fields lists the field names, both handy for serialisation and introspection.

p._asdict()    # {'x': 1, 'y': 2}
Point._fields  # ('x', 'y')

namedtuple versus dataclass

Choose a namedtuple for a small, immutable record that should behave like a tuple. Choose a dataclass when you want mutability, default values, type annotations, or methods. A modern alternative, typing.NamedTuple, adds type hints and a class-based syntax to the namedtuple idea, which many people now prefer for clarity.

from typing import NamedTuple
class Point(NamedTuple):
    x: int
    y: int = 0

This gives the same immutable record with annotations and a default, combining the lightness of a namedtuple with clearer definitions.

Need this solved on your own data?

The library is free and always will be. When the problem is bigger than an answer, we take on the work.

Start a project