2010-01-28 10 views
7

Posso fare riferimento a un fieldame con nome con una variabile?Python: utilizzo di namedtuple._replace con una variabile come nome di campo

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 

risposta

14

tuple sono immutabili, e così sono NamedTuples. Non dovrebbero essere cambiati!

this_prize._replace(choice = "Yay") chiamate _replace con l'argomento parola chiave "choice". Non utilizza choice come variabile e tenta di sostituire un campo con il nome di choice.

this_prize._replace(**{choice : "Yay"}) userebbe qualunque choice è come il nomecampo

_replace restituisce un nuovo namedtuple. È necessario rasterizzarlo: this_prize = this_prize._replace(**{choice : "Yay"})

Utilizzare semplicemente un dict o scrivere una classe normale, invece!

+0

Yay! questo è quello che dovevo sapere. Grazie –

+0

Sto cercando di ottimizzare una struttura dati per la velocità. Speravo di poter usare namedtuples, ma dovrei cambiarli sul posto. Forse dovrò usare qualcos'altro. Vedi: http://stackoverflow.com/questions/2127680/python-optimizing-or-at-least-getting-fresh-ideas-for-a-tree-generator –

+0

Avevo un caso in cui non avrei modificato la maggior parte delle tuple, ma solo alcune di esse, quindi '_replace' è la strada da percorrere. Questa risposta mi ha aiutato molto (più del doc ufficiale). – JulienD

2
>>> 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 
+0

Grazie per la risposta. Capisco cosa intendi. –

+1

Ma davvero, perché stai usando una tupla chiamata per questo? Sembra che tu voglia un titolo. – jcdyer

Problemi correlati