【问题标题】:Storing and Comparing Multiple Attributes in Python在 Python 中存储和比较多个属性
【发布时间】:2018-08-04 02:05:03
【问题描述】:

我正在尝试构建一款 Survivor 游戏,让我可以将存储的角色单独和作为部落成员进行比较。我可以用一个属性来做,但想不出将它扩展到多个属性的最佳方法。

例子:

TribeAStr = {'John': 50, 'Tyler': 55, 'Joe': 90, 'Bob': 55}

# check who is the strongest Survivor
$ strongest = max(TribeAStr, key=TribeAStr.get)

#Remove him from TribeA
del TribeAStr[strongest]

#Check how strong the Tribe is as a whole
$ tribeastrength = sum(TribeAStr.values())

我想做的是让每个幸存者都有自己的属性,然后使用他们的名字作为密钥,然后可以将其拉入与上述类似的场景中。像这样的:

class Survivor:
    def __init__(self, name, str=None, int=None, cha=None, luk=None):
        self.name = name
        self.str = strength
        self.int = intelligence
        self.cha = charisma
        self.luk = luck

TribeA = {}
John = Survivor{'John', 50, 40, 55, 20}
Bob= Survivor{'Bob', 55, 40, 80, 25}
Joe= Survivor{'Joe', 60, 10, 65, 10}
Tyler= Survivor{'Tyler', 56, 30, 15, 25}
TribeA.update('John', 'Bob', 'Joe', 'Tyler')

# check who is the strongest Survivor
$ strongest = max(Survivor, Survivor.str) for Survivor in TribeA

有什么建议吗?

【问题讨论】:

  • 附带说明:我知道strint 显然意味着力量和智力——但是当你的大脑处于 Python 模式而不是 D&D 模式时,它会将它们读取为字符串和整数类型。将strint 用作属性(与将它们用作全局或局部变量名称不同)并不违法或危险,但除非她在 d20 上滚动到 wis 下,否则它仍然会让读者感到厌烦,所以你可能想要至少考虑使用不同的名称。
  • 还有一件事:你为什么允许None 作为所有初始化参数的默认值?你会如何处理一个拥有None 的幸存者str?当您第一次尝试将其与其他人的 str 或 d100 卷或其他内容进行比较时,您只会得到 TypeError

标签: python class dictionary compare


【解决方案1】:

您的第一个问题是语法错误:

John = Survivor{'John', 50, 40, 55, 20}

在 Python 中,您可以像普通函数一样调用构造函数,使用括号:

John = Survivor('John', 50, 40, 55, 20)

你的第二个问题是你不能update 一个只有一个键列表的字典;您需要使用 dict (或键值对列表)对其进行更新。它怎么会知道你想要什么值呢?所以:

TribeA.update({'John': John, 'Bob': Bob, 'Joe': Joe, 'Tyler': Tyler})

但是真的没有理由只为update 它创建一个空字典;一口气创建它:

TribeA = {'John': John, 'Bob': Bob, 'Joe': Joe, 'Tyler': Tyler}

如果每个名字都重复写两次,你可以使用字典理解来解决这个问题:

TribeA = {survivor.name: survivor for survivor in (John, Bob, Joe, Tyler)}

或者,或者,也许您一开始就不想创建这些变量;您可以直接将对象存储在字典中:

TribeA = {}
TribeA['John'] = Survivor('John', 50, 40, 55, 20)
# etc.

您的第三个问题是理解语法错误:

strongest = max(Survivor, Survivor.str) for Survivor in TribeA

您必须将整个理解放在传递给max 的括号内。此外,您想按强度对它们进行排序,因此您希望在这对中,强度排在第一位,而不是发送。最后,如果你的部落是一个字典,你不能只是循环遍历字典——它只是给你钥匙。您需要遍历这些值:

strongest = max((survivor.str, survivor) for survivor in TribeA.values())

但是请注意,这不仅会给你返回最强的幸存者,还会返回两个值,最强幸存者的力量和幸存者。你可以扔掉你不想要的:

_, strongest = max((survivor.str, survivor) for survivor in TribeA.values())

…但最好使用键功能,如Sorting HOWTO 中所述:

strongest = max(TribeA.values(), key=lambda survivor: survivor.str)

【讨论】:

    【解决方案2】:

    这应该可行:

    In [19]: class Survivor:
        ...:     def __init__(self, name, strength=None, intelligence=None, charisma=None, luck=None):
        ...:         self.name = name
        ...:         self.strength = strength
        ...:         self.intelligence = intelligence
        ...:         self.cha = charisma
        ...:         self.luk = luck
    
    In [21]: TribeA = []
        ...: John = Survivor('John', 50, 40, 55, 20)
        ...: Bob= Survivor('Bob', 55, 40, 80, 25)
        ...: Joe= Survivor('Joe', 60, 10, 65, 10)
        ...: Tyler= Survivor('Tyler', 56, 30, 15, 25)
        ...: TribeA.extend([John, Bob, Joe, Tyler])
    
    In [25]: strongest = max(TribeA, key=lambda x: x.strength)
    
    In [26]: strongest.name
    Out[26]: 'Joe'
    

    要从 TribeA 中移除最强的玩家,请使用以下命令:

    TribeA = list(filter(lambda x: x != strongest, TribeA))
    
    # or going by name
    # TribeA = list(filter(lambda x: x.name != strongest.name, TribeA))
    

    【讨论】:

    • 这似乎很好用,谢谢!如果我能打扰您回答最后一个问题 - 如果我想通过使用变量“最强”从 TribeA 中删除“乔”,我会怎么做?我正在尝试使用:del TribeA(strongest) 但是我收到一个错误,即列表索引必须是整数,而不是幸存者。想法?
    【解决方案3】:

    你可以定义一个方法用来确定一个Survivor的整体评分,大概是所有属性中的sum,并用它作为maxkey来确定最强的Survivor

    class Survivor:
        def __init__(self, name, str=None, int=None, cha=None, luk=None):
            self.name = name
            self.str = str
            self.int = int
            self.cha = cha
            self.luk = luk
    
        def overall(self):
            return sum(getattr(self, attr) for attr in ('str', 'int', 'cha', 'luk'))
    
    John = Survivor('John', 50, 40, 55, 20)
    Bob= Survivor('Bob', 55, 40, 80, 25)
    Joe= Survivor('Joe', 60, 10, 65, 10)
    Tyler= Survivor('Tyler', 56, 30, 15, 25)
    TribeA = [John, Bob, Joe, Tyler]
    strongest = max(TribeA, key=Survivor.overall)
    print(strongest.name)
    

    这个输出:

    Bob
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-12
      • 1970-01-01
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多