2010-01-28 4 views
7

¿Puedo hacer referencia a un namedtuple fieldame usando una variable?Python: Usando namedtuple._replace con una variable como un nombre de 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 

Respuesta

14

Las tuplas son inmutables, y también lo son NamedTuples. ¡Se supone que no deben ser cambiados!

this_prize._replace(choice = "Yay") llamadas _replace con la palabra clave argumento "choice". No utiliza choice como variable e intenta reemplazar un campo por el nombre choice.

this_prize._replace(**{choice : "Yay"}) podría usar cualquier choice es como el nombre del campo

_replace devuelve un nuevo NamedTuple. Necesita reasignarlo: this_prize = this_prize._replace(**{choice : "Yay"})

¡Simplemente use una dicción o escriba una clase normal en su lugar!

+0

¡Yay! eso es lo que necesitaba saber. Gracias –

+0

Estoy tratando de optimizar una estructura de datos para la velocidad. Tenía la esperanza de poder usar namedtuples, pero tendría que cambiarlos en su lugar. Quizás tendré que usar algo más. Ver: http://stackoverflow.com/questions/2127680/python-optimizing-or-at-least-getting-fresh-ideas-for-a-tree-generator –

+0

Tuve un caso en el que no modificaría la mayoría de las tuplas, pero solo unas pocas, así que '_replace' es el camino a seguir. Esta respuesta me ayudó mucho (más que el documento oficial). – 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

Gracias por su respuesta. Veo a que te refieres. –

+1

Pero realmente, ¿por qué estás usando una tupla nombrada para esto? Parece que quieres un dict. – jcdyer

Cuestiones relacionadas