9) Idiomatic Data Structures Lesson

Python namedtuple

8 min to complete · By Martin Breuss

Another interesting data structure that Python provides in the collections module is the namedtuple.

What Does namedtuple Do

This data structure can do anything a tuple can do. It still supports the familiar zero-based indexing. It's immutable and has a consistent hash value, which means you can store them in sets and use them as dictionary keys. It even has memory consumption that is similar to regular tuples.

In short, a namedtuple is a tuple that is optimized for readability because it allows you to access the items in the tuple through names rather than indices. This makes namedtuple more readable and easier to work with, as you don't have to remember the position of each item in the tuple.

Python namedtuple Functionality

Additionally, namedtuple supports:

  • Named item access via the dot-notation (the main selling point!)
  • Descriptive string representations that tell you what you're working with
  • Automatically generated docstrings
  • Additional methods and attributes, e.g. ._make(), _asdict(), ._fields

Once you get a bit familiar with this data structure, you might see the advantage of choosing it over a plain tuple.

How to Create a namedtuple

To create a namedtuple, you first need to import it from the collections module. Then, you can define your namedtuple by calling the namedtuple function and passing in two arguments:

  1. The name of the namedtuple
  2. A string containing the names of the items, separated by spaces

For example, imagine that you need to keep track of the geolocations of all the places around the globe that you want to visit. To do this, you could create a namedtuple called Geolocation that has three items: name, lat, and lon:

from collections import namedtuple

Geolocation = namedtuple("Geolocation", "name lat lon")

Once you've defined your namedtuple, you can create instances of it by calling Geolocation with the values for each item as arguments in the order they were defined. For example, you can now record the geolocation for Null Island (0° latitude, 0° longitude) as a namedtuple:

null_island = Geolocation(name="Null Island", lat=0, lon=0)

With this, you've created a namedtuple that holds all the relevant geo-information that you need to put your travel destinations on a map.

Work With a Python namedtuple

To access the items in a namedtuple, you can use either the zero-based indexing or the dot notation. For example, to get the name of Null Island, you can do either of the following:

# Using zero-based indexing
print(null_island[0])  # "Null Island"

# Using dot notation
print(null_island.name)  # "Null Island"

While the geolocation of Null Island may be relatively straightforward to remember, and it frankly doesn't even matter which of the numbers is the latitude and which is the longitude, this gets more challenging with nearly all other locations in the world:

maccu_piccu = Geolocation(name="Maccu Piccu", lat=-13.163108055193145, lon=-72.54496539348477)

Here, the advantage of actually having names for each of the elements in your tuple might become more apparent. Think about comparing how you could access this location when you save it as a namedtuple as opposed to a regular tuple:

maccu_piccu = Geolocation(name="Maccu Piccu", lat=-13.163108055193145, lon=-72.54496539348477)
maccu_piccu_tuple = ("Maccu Piccu", -13.163108055193145, 72.54496539348477)

# Get the latitude from the plain tuple
maccu_piccu_tuple[1]  # -13.163108055193145 - Wait... or was it at index 0? Or index 2? Arrgh!

# Get the latitude from the namedtuple
maccu_piccu.lat  # -13.163108055193145 - Yay!

While creating the namedtuple is more verbose, it quickly pays off in readability if you need to access and work with the elements.

Use Additional Features of a namedtuple

But readability is not the only reason why you might want to use a namedtuple. The data structure comes prepackaged with some additional useful methods.

You can use ._asdict() to convert a namedtuple into a dictionary, which can be useful if you need to modify the values that you're recording in the otherwise immutable namedtuple:

null_island_dict = null_island._asdict()
null_island_dict["name"] = "Null Island is not an island"

modified_null_island = Geolocation(**null_island_dict)
print(modified_null_island)  # Geolocation(name='Null Island is not an island', lat=0, lon=0)

It's good you found that out before going on your camping adventure!

An orange tent sinking into water

Finally, namedtuple has several other useful attributes and methods, such as ._make() which allows you to create a new namedtuple from an iterable, and ._fields which returns a tuple containing the field names of the namedtuple.

Summary: Python namedtuple

  • Python's namedtuple is from the collections module
  • Namedtuple is a convenient and readable data structure
  • Namedtuples can be used as an alternative to regular tuples in cases where you want to access items by name rather than by index

Some namedtuple Functionality

  • Named item access via the dot-notation (the main selling point!)
  • Descriptive string representations that tell you what you're working with
  • Automatically generated docstrings
  • Additional methods and attributes, e.g. ._make(), _asdict(), ._fields