In Python, a namedtuple is an extension of the classic tuple that allows access to its elements by explicit names, while maintaining the lightness and immutability of the tuple.
All of this makes the namedtuple an ideal type for structuring data without needing to create a complete class!
Definition of namedtuple
A namedtuple is a custom type of tuple whose fields can be accessed via a name rather than an index.
This makes the code clearer, especially in functions that return multiple values or manipulate structured data.
Think of it as a tuple but with labels! 😉
Creating a namedtuple
To create a namedtuple, we use collections.namedtuple:
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 5)
print(p.x) # 3
print(p.y) # 5In this example, we create a new data type called Point.
This type acts like a tuple but with named values. This means that instead of accessing data by their position (like p[0]), we can use clear and explicit names (like p.x or p.y in our example).
Then, when we write p = Point(3, 5), we instantiate this namedtuple with values 3 and 5, which will go directly to the x and y parameters we defined when creating it.
So when we use print(p.x) Python will look for the named parameter x (which gives us 3).
Accessing values (index and named keys)
With a namedtuple, it's possible to access values in two ways:
- By their named key (what we just saw);
- But also by their index! 😋
Accessing by named keys
As we saw in our previous example, it's possible to access elements of a namedtuple by named keys:
print(userA.firstname)
Accessing by index
A namedtuple can also be used like a classic tuple:
print(userA[0])Although possible, the advantage of a namedtuple is still to benefit from it with named keys! They bring more readability.
namedtuple vs tuple: what differences?
Why prefer a namedtuple to a simple class or to a raw tuple?
Although the namedtuple relies on its structure, it brings a layer of readability and structure that makes it a much more suitable tool in many concrete cases.
A standard tuple is an immutable sequence, but its elements must be accessed by index. This can quickly harm code clarity, especially if the tuple contains multiple fields.
The namedtuple, on the other hand, allows naming the fields, making their usage explicit and self-documented.
Let's take a speaking example:
# Classic tuple
point = (3, 5)
print(point[0]) # x
print(point[1]) # y
# namedtuple
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(3, 5)
print(p.x) # 3
print(p.y) # 5In the first case, we must remember that index 0 corresponds to x and that 1 corresponds to y. In the second case, the names speak for themselves.
Another advantage: a namedtuple provides additional practical methods like _fields, _asdict() or _replace() (we'll see them right after), which don't exist on classic tuples.
To go further, let's make a summary table:
| Criteria | tuple | namedtuple |
| Element access | By index (t[0]) | By name and index (p.x, p[0]) |
| Code readability | Low (no explicit name) | High (clear field names) |
| Mutability | Immutable | Immutable |
| Field definition | No names (only indexes) | Named fields |
| Utility methods | ❌ None | _fields, _asdict(), _replace() |
| Memory weight / performance | Very light | Slightly heavier |
| Use as key | ✅ Yes | ✅ Yes |
| Representation | (3, 5) | Point(x=3, y=5) |
| Import required? | ❌ No | ✅ Yes (collections) |
In summary: use a tuple for very simple and temporary data, but prefer a namedtuple as soon as you want more readability, structure, or a lightweight class equivalent.
Special methods of namedtuple
Unlike classic tuples, namedtuple provide several very practical built-in methods. They facilitate conversion, updating or inspecting data, while preserving immutability.
View field names with _fields
This property returns a tuple containing the field names defined when creating the namedtuple.
Point = namedtuple("Point", ["x", "y"])
print(Point._fields) # ('x', 'y')
Convert to dictionary with _asdict()
This method transforms a namedtuple instance into an ordered dictionary (OrderedDict). Useful for display, serialization or debugging.
p = Point(3, 5)
print(p._asdict()) # {'x': 3, 'y': 5}
Create a new instance with a modified value thanks to _replace()
Since a namedtuple is immutable, we can't modify its fields. But with _replace(), we can create a copy with one or more modified values.
p2 = p._replace(x=10)
print(p2) # Point(x=10, y=5)
namedtuple vs dataclass: what differences?
Since Python 3.7, dataclass have become a modern and flexible alternative to namedtuple, while bringing more power and flexibility. But they don't completely replace namedtuple: each tool has its usefulness.
Let's make a comparative summary:
| Criteria | namedtuple | dataclass |
| Availability | Since Python 2.6 | Since Python 3.7 |
| Syntax | Less intuitive (dedicated function) | More natural (@dataclass decorator) |
| Immutability by default | ✅ Yes | ❌ No (but possible with frozen=true) |
| Field access | By name (p.x) | By name (p.x) |
| Type hinting | ❌ Not mandatory | ✅ Highly integrated |
| Inheritance | ❌ Limited | ✅ Supported |
| Auto-generated methods | _asdict(), _replace() | __init__(), __repr__(), __eq__() |
| Memory weight | Very light | Slightly heavier |
| Recommended usage | Simple immutable data | Evolving and typed data structures |
For example, this is a dataclass equivalent to the namedtuple we saw earlier:
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(3, 5)
print(p.x) # 3
Frequently asked questions about namedtuple
Here are the most frequent questions when talking about namedtuple! 😋
What's the difference between tuple and namedtuple?
A tuple is indexed by position. A namedtuple adds explicit names to fields, making the code clearer.
Can we modify a namedtuple?
No, namedtuple are immutable. Use _replace() to create a new version with a modified value.
Should I use namedtuple or dataclass?
Use namedtuple for simple and immutable structures, and dataclass if you need more flexibility, like inheritance, default values, or custom methods.
What's the best Python training to learn from scratch?
Surely this Python training up to date with the latest features!