2010-01-28 20 views
7

Kann ich einen namedtuple Feldname mithilfe einer Variablen referenzieren?Python: Verwenden von namedtuple._replace mit einer Variablen als Feldname

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 

Antwort

14

Tupeln sind unveränderlich, und so sind NamedTuples. Sie sollen nicht geändert werden!

this_prize._replace(choice = "Yay") Aufrufe _replace mit dem Schlüsselwort Argument "choice". Es verwendet choice nicht als Variable und versucht, ein Feld mit dem Namen choice zu ersetzen.

this_prize._replace(**{choice : "Yay"}) würde verwenden, was choice als Feldname ist

_replace gibt einen neuen NamedTuple. Sie müssen es neu zuordnen: this_prize = this_prize._replace(**{choice : "Yay"})

Verwenden Sie einfach ein Diktat oder schreiben Sie stattdessen eine normale Klasse!

+0

Yay! das musste ich wissen. Danke –

+0

Ich versuche eine Datenstruktur für Geschwindigkeit zu optimieren. Ich hatte gehofft, ich könnte Nametuples verwenden, aber ich würde sie an Ort und Stelle ändern müssen. Vielleicht muss ich etwas anderes benutzen. Siehe: http://stackoverflow.com/questions/2127680/python-optimizing-or-least-getting-fresh-ideas-for-a-tree-generator –

+0

Ich hatte einen Fall, wo ich am meisten nicht ändern würde von den Tupeln, aber nur ein paar von ihnen, also '_replace' ist der Weg zu gehen. Diese Antwort hat mir sehr geholfen (mehr als das offizielle Dokument). – 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

Vielen Dank für Ihre Antwort. Ich verstehe was du meinst. –

+1

Aber warum verwenden Sie ein benanntes Tupel dafür? Es klingt wie du ein Diktat willst. – jcdyer