238

The standard library namedtuple class looks to me like a way to make tuples more like dictionaries. How do namedtuples compare to dicts? When should we use them? Do they work with non-hashable types?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
Jack_of_All_Trades
  • 10,942
  • 18
  • 58
  • 88
  • 2
    Take a look at this question - http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python – ronakg Mar 26 '12 at 12:45
  • 6
    ^-- agreed: [2970608](http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python) has named tuple FAQs and this one asks for comparison to dict. – Tom Hundt Apr 04 '18 at 16:39

2 Answers2

271

In dicts, only the keys have to be hashable, not the values. namedtuples don't have keys, so hashability isn't an issue.

However, they have a more stringent restriction -- their key-equivalents, "field names", have to be strings.

Basically, if you were going to create a bunch of instances of a class like:

class Container:
    def __init__(self, name, date, foo, bar):
        self.name = name
        self.date = date
        self.foo = foo
        self.bar = bar

mycontainer = Container(name, date, foo, bar)

and not change the attributes after you set them in __init__, you could instead use

Container = namedtuple('Container', ['name', 'date', 'foo', 'bar'])

mycontainer = Container(name, date, foo, bar)

as a replacement.

Of course, you could create a bunch of dicts where you used the same keys in each one, but assuming you will have only valid Python identifiers as keys and don't need mutability,

mynamedtuple.fieldname

is prettier than

mydict['fieldname']

and

mynamedtuple = MyNamedTuple(firstvalue, secondvalue)

is prettier than

mydict = {'fieldname': firstvalue, 'secondfield': secondvalue}

Finally, namedtuples are ordered, unlike regular dicts, so you get the items in the order you defined the fields, unlike a dict.

agf
  • 171,228
  • 44
  • 289
  • 238
  • 44
    Also, quoting Raymondh: "Instances of named tuples use no more space than regular tuples. The field name properties are stored in the namedtuple class." https://twitter.com/raymondh/status/524660721968107521 – Moberg Oct 31 '14 at 07:48
  • 7
    One more thing to note is that the named tuple can also be initialized as `mynamedtuple = MyNamedTuple(fieldname=firstvalue, secondfield=secondvalue)` – Bharat Khatri Feb 10 '18 at 09:55
  • 2
    You can make the instantiatiation even prettier/simpler with `Container = namedtuple('Container', 'name date foo bar')` – stackPusher Mar 15 '18 at 15:49
  • 1
    If you need more flexibility, [attrs](http://www.attrs.org/en/stable/why.html#namedtuples) is an interesting alternative to namedtuple. – Christian Long Aug 14 '18 at 15:11
  • 19
    If you're using Python 3.7 or CPython 3.6 `dicts` are [insertion ordered](https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6). – Boris Verkhovskiy Jan 27 '19 at 21:18
  • 1
    @Boris Good info, but still different from field definition ordering and in many situations just as unknown as random ordering. – agf Jan 28 '19 at 11:18
  • NamedTuples take advantage of attribute autocompletion provided by many IDEs, since they use attribute access rather than key lookup. No more checking `parse_x_data()` source code for a dict signature. – Nathaniel Jones Mar 30 '23 at 16:56
47

Tuples are immutable, whether named or not. namedtuple only makes the access more convenient, by using names instead of indices. You can only use valid identifiers for namedtuple, it doesn't perform any hashing — it generates a new type instead.

Cat Plus Plus
  • 125,936
  • 27
  • 200
  • 224