3

I have a program where I am keeping the statistics of objects in the game in a dict, like this:

Weapon = namedtuple("Weapon", ["owned", "damage", "price", "accuracy"])

weapons = {
    "fists":    Weapon(True, 2, None, 75),
    "knife":    Weapon(False, 4, 50, 95),
    "sword":    Weapon(False, 6, 100, 90),
    "pistol":   Weapon(False, 8, 250, 65),
    "rifle":    Weapon(False, 10, 500, 80),
    "rpg":      Weapon(False, 20, 1000, 100)
}

How would I edit The owned value from inside of a function?

Joshua
  • 40,822
  • 8
  • 72
  • 132
  • 3
    Namedtuples are immutable. You could use recordtypes. http://stackoverflow.com/questions/2970608/what-are-named-tuples-in-python – wrdeman Mar 04 '15 at 19:12
  • 1
    @wrdeman you can use _replace on the namedtuple and re-assign to the dictionary. See my answer – Peter Wood Mar 04 '15 at 19:15

2 Answers2

3

namedtuple is immutable. Why not use classes? Your code will be cleaner, more organized, modular, and easier to reuse.

class Weapon:
    def __init__(self, owned, damage, price, accuracy):
        self.owned = owned
        self.damage = damage
        self.price = price
        self.accuracy = accuracy

    def flip_weapon_owned_value(self):
        self.owned = False if self.owned else True
        print "\n", self.owned


weapons = {
    'fists' :  Weapon(True, 2, None, 75),
    'knife' :  Weapon(False, 4, 50, 95),
    'sword' :  Weapon(False, 6, 100, 90),
    'pistol' : Weapon(False, 8, 250, 65),
    'rifle' :   Weapon(False, 10, 500, 80),
    'rpg' :     Weapon(False, 20, 1000, 100)
}

> weapons['fists'].flip_weapon_owned_value()
> False

> weapons['fists'].flip_weapon_owned_value()
> True
Boa
  • 2,609
  • 1
  • 23
  • 38
2

A namedtuple allows you to clone it with updated values. See _replace. It starts with an underscore so it won't clash with any of your attribute names.

You need to re-assign this updated clone to the dictionary key:

weapons = ... # as above

def main():
    do_something(weapons)

def do_something(weapons):
    weapons['fists'] = weapons['fists']._replace(owned=False)
Peter Wood
  • 23,859
  • 5
  • 60
  • 99