collections.namedtuple
In this lesson, you’ll learn about the collections.namedtuple
data structure. namedtuple
is a subclass of tuples and creates tuple-like immutable objects:
>>> from collections import namedtuple
>>> Car = namedtuple("Car", ["color", "make", "model", "mileage"])
>>> my_car = Car(color="midnight silver", make="Tesla", model="Model Y", mileage=5)
>>> my_car.color
'midnight silver'
You can read more about namedtuple
in the documentation for the Python collections module.
00:00
namedtuple
s are a subclass of tuples, which really helps you if you’re trying to define immutable classes. So, instead of doing something like class Car:
def __init__(self)
and maybe the color
and the make
, model
, mileage
, and then inside you do self.color = color
, self.make = make
, blah, blah, blah, and then you instantiate your Car()
like that. Obviously, it fails, but if you’re going to do something like that, and you don’t want people to be able to mutate that Car
, then you’d use a namedtuple
. You’d also use a namedtuple
instead if you have a tuple, like tup = (1, True, object(), -1)
, with a bunch of different types of values for things.
00:42
Or maybe it’s a very large tuple and you want to give them names to access each value, instead of doing tup[0]
or tup[1]
.
00:52
So, let’s see how this works. namedtuple
is part of the collections
module, so from collections import namedtuple
.
01:01
I’m going to clear the output, just so it’s a little bit easier to see, and then do something like this. Car = namedtuple
, "Car"
—so, this is the name of the class—and then a string with all of the fields, with a space in between.
01:15
This is because under the hood this will call .split()
, and then these will be the fields. You could also do something like Car = namedtuple
, "Car"
, and then explicitly pass in a list: ["color", "make", "model", "mileage"]
et cetera.
01:35
Car
is __main__.Car
. I’m not sure why it says that but all you need to know is that you can create a Car
just like how you would a class. So, Car("midnight silver", "Tesla", "Model Y", 5)
.
01:52
So, this will create a Car
with color "midnight silver"
, make "Tesla"
, model "Model Y"
, and mileage 5
.
02:00
Save it into my_car
. my_car
now looks like this, and the namedtuple
has a nice built-in __repr__()
method, so that it’ll look nice, like this.
02:10
You could also define the Car
with those explicitly passed in. color=
"midnight silver"
, make="Tesla"
,
02:20
model="Model Y"
, and mileage=5
.
02:25
Cool. So now, you can access it like a class—my_car.color
is "midnight silver"
, my_car.model
is "Model Y"
.
02:34
But the thing is—you cannot mutate this. my_car.model = "Model X"
—can't set attribute
.
02:43
So, namedtuple
s are really nice if you want to find a class really easily, and you don’t want them to mutate it. It’s also technically a tuple, like isinstance(my_car, tuple)
.
02:53
So, I guess you could access the values with indices as well, which sort of defeats the purpose, but it’s just something cool. my_car[1]
, [2]
, et cetera.
03:02
So, there are some other useful namedtuple
methods and I’ll link the documentation below. This concludes the section on how to leverage data structures effectively.
03:11 In the next section, you’ll learn about more useful built-in modules.
Balaviknesh Sekar on June 16, 2020
Can we give default value, if some of the required arguments are missing in namedtuple ?
Geir Arne Hjelle RP Team on June 17, 2020
Hi Bala,
yes, it’s possible to add default values. This was added in Python 3.7 - so it won’t work in 3.6 and earlier. You can use defaults=...
:
>>> Car = namedtuple("Car", ["color", "make", "model", "mileage"], defaults=["v1", 0])
>>> Car("blue", "Honda")
Car(color='blue', make='Honda', model='v1', mileage=0)
The defaults work from the back, so that when I’m giving two default values here, those are matched with last two fields of the namedtuple
.
You may also investigate the default values:
>>> Car._field_defaults
{'model': 'v1', 'mileage': 0}
Another option, which I usually find easier to read is using typing.NamedTuple
instead of collections.namedtuple
. It’s essentially a drop-in replacement, but uses a different syntax. The example on top will look something like this:
>>> from typing import NamedTuple
>>> class Car(NamedTuple):
... color: str
... make: str
... model: str = "v1"
... mileage: int = 0
...
>>> my_car = Car(color="midnight silver", make="Tesla", model="Model Y")
>>> my_car.color
'midnight silver'
>>> my_car
Car(color='midnight silver', make='Tesla', model='Model Y', mileage=0)
I changed the example slightly to also show how to use default values.
Another benefit of NamedTuple
is that you can document the type of each field as well. However (as with all type hints) these are not enforced by Python, so you could use any expression there (although that could be confusing down the line).
Roman Makarov on Aug. 15, 2023
Perhaps it would be worth mentioning dataclasses as well, which provide similar functionality but are based on dictionaries and are mutable.
Become a Member to join the conversation.
James Uejio RP Team on April 27, 2020
Here is the Python documentation on namedtuple: Python collections module