Using namedtuple._replace with a variable as a fieldname

Peter Stewart picture Peter Stewart · Jan 28, 2010 · Viewed 11.3k times · Source

Can I reference a namedtuple fieldame using a variable?

from collections import namedtuple
import random 

Prize = namedtuple("Prize", ["left", "right"]) 

this_prize = Prize("FirstPrize", "SecondPrize")

if random.random() > .5:
    choice = "left"
else:
    choice = "right"
    
#retrieve the value of "left" or "right" depending on the choice
print "You won", getattr(this_prize,choice)
 
#replace the value of "left" or "right" depending on the choice
this_prize._replace(choice  = "Yay") #this doesn't work

print this_prize

Answer

Jochen Ritzel picture Jochen Ritzel · Jan 28, 2010

Tuples are immutable, and so are NamedTuples. They are not supposed to be changed!

this_prize._replace(choice = "Yay") calls _replace with the keyword argument "choice". It doesn't use choice as a variable and tries to replace a field by the name of choice.

this_prize._replace(**{choice : "Yay"} ) would use whatever choice is as the fieldname

_replace returns a new NamedTuple. You need to reasign it: this_prize = this_prize._replace(**{choice : "Yay"} )

Simply use a dict or write a normal class instead!