(TIL) Python: An improved tuple

1 minute read

A downside of plain tuples is that the data you store in them can only be pulled out by accessing it through integer indexes. You can’t give names to individual properties stored in a tuple. This can impact code readability.

Also, a tuple is always an ad-hoc structure. It’s hard to ensure that two tuples have the same number of fields and the same properties stored on them. This makes it easy to introduce “slip-of-the-mind” bugs by mixing up the field order.

namedtuples aim to solve these two problems.

namedtuples are immutable just like regular tuples. Once you store something in them you can’t modify it.

Each object stored in a namedtuple can be accessed through a unique (human-readable) identifier. This frees you from having to remember integer indexes, or resorting to workarounds like defining integer constants as mnemonics for your indexes. You can still access the values by their index. That way namedtuples can be used as a drop-in replacement for regular tuples.

How to create a namedtuple:

from collections import namedtuple
Car = namedtuple('Car' , 'color mileage')

You can also pass a list with string field names. The advantage of using a proper list is that it’s easier to reformat this code if you need to split it across multiple lines:

Car = namedtuple('Car', [
...     'color',
...     'mileage',
... ])

You’ll even get a nice string representation for free, which saves some typing and redundancy.

When it comes to memory usage namedtuples are also “better” than regular classes and just as memory efficient as regular tuples.

The namedtuple’s ._fields property gives you a list of the constituent field names.

The _asdict() helper returns the contents of a namedtuple as a dictionary. This is great for avoiding typos when generating JSON-output, for example.

The _replace() function creates a (shallow) copy of a namedtuple and allows you to selectively replace some of its fields.

The _make() classmethod can be used to create new instances of a namedtuple from a sequence or iterable.

From dbader.org.