Search code examples
pythonnamedtuple

Mutable default argument for a Python namedtuple


I came across a neat way of having namedtuples use default arguments from here.

from collections import namedtuple
Node = namedtuple('Node', 'val left right')
Node.__new__.__defaults__ = (None, None, None)
Node()

Node(val=None, left=None, right=None)

What would you do if you would want the default value for 'right' to be a empty list? As you may know, using a mutable default argument such as a list is a no no.

Is there a simple way to implement this?


Solution

  • You can't do that that way, because the values in __defaults__ are the actual default values. That is, if you wrote a function that did had someargument=None, and then checked inside the function body with someargument = [] if someargument is None else someargument or the like, the corresponding __defaults__ entry would still be None. In other words, you can do that with a function because in a function you can write code to do whatever you want, but you can't write custom code inside a namedtuple.

    But if you want default values, just make a function that has that logic and then creates the right namedtuple:

    def makeNode(val=None, left=None, right=None):
        if right is None:
            val = []
        return Node(val, left, right)