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
                Since a named tuple is a tuple, and tuples are immutable, it is impossible to change the value of a field. In this case, we have to use another private method _replace() to replace values of the field. The _replace() method will return a new named tuple.
Python's namedtuple() is a factory function available in collections . It allows you to create tuple subclasses with named fields. You can access the values in a given named tuple using the dot notation and the field names, like in obj. attr .
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.
@Antimony: pickle handles namedtuple classes just fine; classes defined in a function local namespace not so much.
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!
>>> choice = 'left'
>>> this_prize._replace(**{choice: 'Yay'})         # you need to assign this to this_prize if you want
Prize(left='Yay', right='SecondPrize')
>>> this_prize
Prize(left='FirstPrize', right='SecondPrize')         # doesn't modify this_prize in place
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With