【问题标题】:Editing dict values in a method在方法中编辑 dict 值
【发布时间】:2015-03-04 19:03:33
【问题描述】:

我有一个程序,我将游戏中对象的统计信息保存在一个字典中,如下所示:

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)
}

如何从函数内部编辑 owned 值?

【问题讨论】:

  • 命名元组是不可变的。您可以使用记录类型。 stackoverflow.com/questions/2970608/…
  • @wrdeman 您可以在 namedtuple 上使用 _replace 并重新分配给字典。看我的回答

标签: python function dictionary immutability key-value


【解决方案1】:

namedtuple 是不可变的。为什么不使用类?您的代码将更简洁、更有条理、更模块化且更易于重用。

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

【讨论】:

  • self.owned = !self.owned 更简单。
【解决方案2】:

namedtuple 允许您使用更新的值克隆它。见_replace。它以下划线开头,因此不会与您的任何属性名称冲突。

您需要将此更新后的克隆重新分配给字典键:

weapons = ... # as above

def main():
    do_something(weapons)

def do_something(weapons):
    weapons['fists'] = weapons['fists']._replace(owned=False)

【讨论】:

  • 我最初尝试过并收到此错误消息:AttributeError:无法设置属性
  • 为什么不使用新的 namedtuple 实例替换该条目,而不是尝试修改看似不可变的数据类型?
  • 噢!这正是_replace 所做的。我的错。
  • @mattm 它没有标记为私有,所以它不会与您的属性发生冲突。
  • 引用:In addition to the methods inherited from tuples, named tuples support three additional methods and one attribute. To prevent conflicts with field names, the method and attribute names start with an underscore.
猜你喜欢
  • 2023-03-11
  • 1970-01-01
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 2021-12-18
  • 1970-01-01
  • 2018-06-02
  • 1970-01-01
相关资源
最近更新 更多