Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

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:

Python
>>> 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 namedtuples 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, namedtuples 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.

Avatar image for James Uejio

James Uejio RP Team on April 27, 2020

Here is the Python documentation on namedtuple: Python collections module

Avatar image for Balaviknesh Sekar

Balaviknesh Sekar on June 16, 2020

Can we give default value, if some of the required arguments are missing in namedtuple ?

Avatar image for Geir Arne Hjelle

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).

Avatar image for Roman Makarov

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.