collections.namedtuple

A factory, not a class: namedtuple() returns a new class whose instances are ordinary immutable tuples with names attached. Field names must be valid, non-keyword identifiers that do not start with an underscore.

collections functionPython 2.6+Live demo
Common call
Point = namedtuple('Point', 'x y')
Returns
a class — Point(1, 2) → Point(x=1, y=2)
Replaces
plain tuples indexed by position, small throwaway classes
Watch out
immutable: use p._replace(x=5), not p.x = 5
collections.namedtuple(typenametypename — Name of the new class (shown in its repr).type: str · required, field_namesfield_names — Field names as a list, or one string separated by spaces and/or commas: 'x y' or 'x, y'.type: str | iterable[str] · required, *, renamerename — Replace invalid names with positional names _0, _1 … instead of raising ValueError.type: bool · default: False=False, defaultsdefaults — Default values for the RIGHTMOST fields.type: iterable | None · default: None=None, modulemodule — Sets __module__ of the new class (helps pickling).type: str | None · default: None=None)
→ type

Demo

Live evaluation
Type the field names as one string. Invalid names raise ValueError with the reason.
Try:
Inputs
fieldsstre.g. 'x y' or 'x, y'
Code
from collections import namedtuple
Point = namedtuple('Point', 'x, y z')
Point._fields
Result
('x', 'y', 'z')

Soft keywords such as match, case and type are allowed as field names; only hard keywords like class are rejected. rename=True replaces each bad name by an underscore plus its position, so the second "id" becomes _3 because it is the fourth field. _make needs exactly as many values as there are fields: TypeError: Expected 2 arguments, got 3.

Parameters

NameTypeRequiredDescription
typenamestryesName of the new class (shown in its repr).
field_namesstr | iterable[str]yesField names as a list, or one string separated by spaces and/or commas: 'x y' or 'x, y'.
renameboolno (False)Replace invalid names with positional names _0, _1 … instead of raising ValueError.
defaultsiterable | Noneno (None)Default values for the RIGHTMOST fields.
modulestr | Noneno (None)Sets __module__ of the new class (helps pickling).

Return value

type — A new tuple subclass named typename.

Attributes

AttributeTypeMeaning
_fieldstuple[str, ...]Field names, in order.
_field_defaultsdictField name → default value (3.7+).
_make(iterable)classmethodBuild an instance from any iterable of exactly len(_fields) items.
_asdict()methodA new dict mapping field names to values (a plain dict since 3.8).
_replace(**kw)methodA new instance with some fields replaced; unknown names raise TypeError (3.13; ValueError before).

Common patterns

Readable function results
Return a namedtuple instead of a bare tuple; callers can still unpack it.
from collections import namedtuple
Stats = namedtuple('Stats', 'mean median')
def stats(xs):
    return Stats(sum(xs) / len(xs), sorted(xs)[len(xs) // 2])
Rows from CSV
_make turns each row list into a record; rename=True tolerates odd headers.
import csv
from collections import namedtuple
with open('data.csv', newline='') as f:
    reader = csv.reader(f)
    Row = namedtuple('Row', next(reader), rename=True)
    rows = [Row._make(r) for r in reader]
Defaults for trailing fields
defaults apply to the rightmost fields.
from collections import namedtuple
Account = namedtuple('Account', 'owner balance', defaults=[0])
Typed alternative
typing.NamedTuple builds the same kind of class with annotations.
from typing import NamedTuple
class Point(NamedTuple):
    x: float
    y: float = 0.0

Examples

1. Define and create
from collections import namedtuple Point = namedtuple('Point', 'x y') Point(3, y=4)
Returns
Point(x=3, y=4)
2. Still a tuple
from collections import namedtuple Point = namedtuple('Point', 'x y') p = Point(3, 4) (p.x, p[1], tuple(p), isinstance(p, tuple))
Returns
(3, 4, (3, 4), True)
3. _asdict
from collections import namedtuple Point = namedtuple('Point', 'x y') Point(3, 4)._asdict()
Returns
{'x': 3, 'y': 4}
4. _replace returns a new instance
from collections import namedtuple Point = namedtuple('Point', 'x y') Point(3, 4)._replace(x=10)
Returns
Point(x=10, y=4)
5. Defaults fill from the right
from collections import namedtuple Account = namedtuple('Account', 'owner balance', defaults=[0]) (Account('ada'), Account._field_defaults)
Returns
(Account(owner='ada', balance=0), {'balance': 0})
6. Missing argument
from collections import namedtuple Point = namedtuple('Point', 'x y') Point(1)
Returns
TypeError: Point.__new__() missing 1 required positional argument: 'y'
7. Keyword field name
from collections import namedtuple namedtuple('Row', 'id class')
Returns
ValueError: Type names and field names cannot be a keyword: 'class'

Pitfalls

1. Assigning to a field
Instances are immutable tuples. _replace builds a modified copy.
p.x = 5
from collections import namedtuple
Point = namedtuple('Point', 'x y')
p = Point(1, 2)
p.x = 5
AttributeError: can't set attribute
p._replace(x=5)
from collections import namedtuple
Point = namedtuple('Point', 'x y')
p = Point(1, 2)
p._replace(x=5)
Point(x=5, y=2)
2. Mutable default values are shared
A default list is one object used by every instance.
defaults=[[]]
from collections import namedtuple
Bag = namedtuple('Bag', 'items', defaults=[[]])
a, b = Bag(), Bag()
a.items.append(1)
b.items
[1]
pass a fresh list
from collections import namedtuple
Bag = namedtuple('Bag', 'items')
a, b = Bag([]), Bag([])
a.items.append(1)
b.items
[]
3. Unknown field in _replace
Python 3.13 raises TypeError here (earlier versions raised ValueError).
_replace(z=...)
from collections import namedtuple
Point = namedtuple('Point', 'x y')
Point(1, 2)._replace(z=3)
TypeError: Got unexpected field names: ['z']
check _fields
from collections import namedtuple
Point = namedtuple('Point', 'x y')
'z' in Point._fields
False

When to use

Use it
  • Small immutable records and function return values
  • Tuples that are already passed around, made self-documenting
  • Rows from CSV or database cursors
Reach for something else
  • Mutable records, validation, methods → dataclasses
  • Type annotations on the fields → typing.NamedTuple
  • A mutable attribute bag → types.SimpleNamespace

Notes

CPython impl
Lib/collections/__init__.py — namedtuple builds the class at run time (its __new__ is created with eval of a generated lambda) and adds a property per field
Versions
rename 3.1; module 3.6; defaults and _field_defaults 3.7; _asdict returns a plain dict since 3.8; _replace raises TypeError for bad names since 3.13 (docs.python.org)
Field names
Must be identifiers, not keywords, and not start with an underscore; soft keywords such as match, case and type are allowed

FAQ

A tuple subclass created by collections.namedtuple('Name', 'field1 field2'). Instances behave like normal tuples (indexing, unpacking, immutability) but also have named attributes and a readable repr such as Name(field1=1, field2=2).