Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

One big advantage of using namedtuples, aside from the immutability I mentioned elsewhere, is that you can rely on a namedtuple having particular fields. So if you're using dictionaries, you have to worry about KeyError wherever the dict is used, but if you're using namedtuples, you can't create them without assigning values to all of the fields. Dictionaries are still great for their intended purpose -- to represent a mapping -- but namedtuples are nicer if what you really want is a lightweight object.


Setting default values for the namedtuple requires subclassing it, though, which is its own little bag of fun. See all the wailing and gnashing of teeth on SO: https://stackoverflow.com/search?q=namedtuple+subclass


If you're using Python 3.6, it's a lot easier now. You can do:

from typing import NamedTuple

class Point(NamedTuple): x: float y: float = 0.0

and then Point(1.0).y == 0.0.


That's quite nice!


When this is an issue, I tend to create a namedtuple with default values for the fields at the same time I'm defining the namedtuple type itself.

    NT = namedtuple("NT", ('a', 'b'))
    default_NT = NT(42, 'foo')
And then later, if I want to initialize only one field:

    my_new_NT = default_NT._replace(a=7)


I guess that works, but it's a pretty big departure from the expected API of a normal namedtuple, or any other object-with-constructor, for that matter.


If you really want it to look more traditional, you could do:

    NT.new = lambda **kwargs: NT(42, 'foo')._replace(**kwargs)
Now you can make NT objects like so:

    nt1 = NT.new()
    nt2 = NT.new(b='bar')
You can call it something else if calling it "new" makes you feel weird. (I'd call it something else, but naming things is hard.)




Consider applying for YC's Fall 2026 batch! Applications are open till July 27.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: