Python’s namedtuple in the collections module allows you to create immutable sequences with named fields, providing a more readable and Pythonic way to handle tuples. You use namedtuple to access values with descriptive field names and dot notation, which improves code clarity and maintainability.
By the end of this tutorial, you’ll understand that:
- Python’s
namedtupleis a factory function that creates tuple subclasses with named fields. - The main difference between
tupleandnamedtupleis thatnamedtupleallows attribute access via named fields, enhancing readability. - The point of using
namedtupleis to improve code clarity by allowing access to elements through descriptive names instead of integer indices. - Some alternatives to
namedtupleinclude dictionaries, data classes, andtyping.NamedTuple.
Dive deeper into creating namedtuple classes, exploring their powerful features, and writing Python code that’s easier to read and maintain.
Get Your Code: Click here to download the free sample code that shows you how to use namedtuple to write Pythonic and clean code.
Take the Quiz: Test your knowledge with our interactive “Write Pythonic and Clean Code With namedtuple” quiz. You’ll receive a score upon completion to help you track your learning progress:
Interactive Quiz
Write Pythonic and Clean Code With namedtupleIn this quiz, you'll test your understanding of Python's namedtuple() factory function from the collections module.
Getting to Know namedtuple in Python
Python’s namedtuple() is a factory function that’s available in the collections module. It allows you to create a tuple subclass with named fields. These named fields let you to access the values in a given named tuple using dot notation and field names—for example, my_tuple.field_name.
Python’s namedtuple was created to improve code readability by providing a way to access values using descriptive field names instead of integer indices, which often don’t provide any context on what the values are. This feature also makes the code cleaner and more maintainable.
In contrast, accessing values by index in a regular tuple can be frustrating, hard to read, and error-prone. This is especially true if the tuple has a lot of fields and is constructed far away from where you’re using it.
Note: In this tutorial, you’ll find different terms used to refer to Python’s namedtuple, its factory function, and its instances.
To avoid confusion, here’s a summary of how each term is used throughout the tutorial:
| Term | Meaning |
|---|---|
namedtuple() |
The factory function |
namedtuple, namedtuple class |
The tuple subclass returned by namedtuple() |
namedtuple instance, named tuple |
An instance of a specific namedtuple class |
You’ll find these terms used with their corresponding meaning throughout the tutorial.
Besides providing named fields, named tuples in Python offer the following features:
- Are immutable data structures
- Can have a hash value and work as dictionary keys
- Can be stored in sets when they have a hash value
- Generate a basic docstring using the type and field names
- Provide a helpful string representation that displays the tuple content in a
name=valueformat - Support indexing and slicing
- Provide additional methods and attributes, such as
._make(),_asdict(), and._fields - Are backward compatible with regular tuples
- Have similar memory usage to regular tuples
You can use namedtuple instances wherever you need a tuple-like object. They offer the added benefit of accessing values using field names and dot notation, which makes your code more readable and Pythonic.
With this brief introduction to namedtuple and its general features, you’re ready to explore how to create and use them effectively in your own code.
Creating Tuple-Like Classes With the namedtuple() Function
You use a namedtuple() to create an immutable, tuple-like sequence with named fields. A popular example that you’ll often find in resources about namedtuple is defining a class to represent a mathematical point.
Depending on the problem, you’ll probably want to use an immutable data structure to represent your points. Here’s how you can create a two-dimensional point using a regular tuple:
>>> # Create a 2D point as a regular tuple
>>> point = (2, 4)
>>> point
(2, 4)
>>> # Access coordinate x
>>> point[0]
2
>>> # Access coordinate y
>>> point[1]
4
>>> # Try to update a coordinate value
>>> point[0] = 100
Traceback (most recent call last):
...
TypeError: 'tuple' object does not support item assignment
In this example, you create an immutable, two-dimensional point using a regular tuple. This code works. You have a point with two coordinates that you can access by index. The point is immutable, so you can’t modify the coordinates. However, do you think this code is readable? Can you tell upfront what the 0 and 1 indices mean?
To improve clarity, you can use a namedtuple like in the following code. Note that you need to import the function from the collections module first:
>>> from collections import namedtuple
>>> # Create a namedtuple type, Point
>>> Point = namedtuple("Point", "x y")
>>> point = Point(2, 4)
>>> point
Point(x=2, y=4)
>>> # Access the coordinates by field name
>>> point.x
2
>>> point.y
4
>>> # Access the coordinates by index
>>> point[0]
2
>>> point[1]
4
>>> point.x = 100
Traceback (most recent call last):
...
AttributeError: can't set attribute
>>> issubclass(Point, tuple)
True
Now you have a Point class with two appropriately named fields, .x and .y. Your point provides a descriptive string representation by default: Point(x=2, y=4).
You can access the coordinates with dot notation and the field names, which is convenient, readable, and explicit. You can also use indices to access each coordinate’s value if you prefer.
Note: As with regular tuples, named tuples are immutable. However, the values they store don’t necessarily have to be immutable.
It’s completely valid to create a tuple or a named tuple that holds mutable values:
>>> from collections import namedtuple
>>> Person = namedtuple("Person", "name children")
>>> john = Person("John Doe", ["Timmy", "Jimmy"])
>>> john
Person(name='John Doe', children=['Timmy', 'Jimmy'])
>>> id(john.children)
139695902374144
>>> john.children.append("Tina")
>>> john
Person(name='John Doe', children=['Timmy', 'Jimmy', 'Tina'])
>>> id(john.children)
139695902374144
>>> hash(john)
Traceback (most recent call last):
...
TypeError: unhashable type: 'list'
You can create named tuples that contain mutable objects. Then, you can modify the mutable objects in the underlying tuple. However, this doesn’t mean that you’re modifying the tuple itself. The tuple will continue being the same object.
Finally, tuples or named tuples with mutable values aren’t hashable, as you saw in the above example.
Finally, since namedtuple classes are subclasses of tuple, they’re immutable as well. So if you try to change the value of a coordinate, then you’ll get an AttributeError.
Supplying Required Arguments
As you learned before, namedtuple() is a factory function rather than a data structure. To create a new namedtuple class, you need to provide two positional arguments to the function:
typenameprovides the class name for thenamedtupleclass returned bynamedtuple(). You need to pass a string with a valid Python identifier to this argument.