【问题标题】:Beginners python. Best way to store different amount of items for each key?初学者蟒蛇。为每个键存储不同数量的项目的最佳方法?
【发布时间】:2018-03-17 20:42:54
【问题描述】:

我是编程的初学者(也是一个老年人),所以我真的不知道如何正确表达我想要的东西。我已尝试尽可能详尽地描述我的问题,因此非常感谢您的耐心等待!

我想存储与每个用户关联的获胜分数。

  • 每个用户的获胜分数都会不同。
  • 我不需要将用户的名字和姓氏分开,它们都可以是一个字符串。
  • 我不需要以任何方式对分数进行排序,也不需要更改它们。
  • 我只需要能够在用户获胜时添加分数并按获胜次数对用户进行排序。
  • 我会提取所有的中奖分数进行统计,但统计不会关注哪个分数属于哪个用户。
  • 一旦程序停止,它就可以全部从内存中删除。

从我目前的研究来看,我最好的选择似乎是创建一个用户类,我在其中存储一个列表并每次都添加到列表中。或者为每个用户创建一个带有键的字典。但是由于每个用户可能有不同数量的获胜分数,我不知道我是否可以使用字典(除非每个键都与一个列表相关联?)。我认为我不需要像 numpy 数组这样的东西,因为我想创建非常简单的统计数据,而不用担心什么分数属于哪个用户。 我需要考虑不使用不必要的内存等,特别是因为每个用户可能有一百个获胜分数。但是我真的找不到关于字典与类的好处的明确信息。编程社区非常乐于助人并且充满了答案,但不幸的是我经常不明白答案。

非常感谢我能得到的任何帮助!不要害怕告诉我我的想法很愚蠢,我想学习如何像程序员一样思考。

【问题讨论】:

  • 使用带有列表值的字典没有问题。字典实际上在 python 中非常有效,并且在“隐藏”的任何地方都使用(也在类中)。我的第一种方法是使用带有分数列表作为值的普通字典。如果您以后需要更大的灵活性,则可以切换到具有附加功能的自定义类。也许你觉得这个video 的话题很有趣。

标签: python list dictionary key-value


【解决方案1】:

这是一个很好的问题,因为它讨论了两种可能的解决方案。基于类的解决方案和基于字典的解决方案。基于类的解决方案更加优雅和通用,所以我将描述它。

class User(object):
    def __init__(self, scores, name): #Where scores is a list of their scores
        self.scores = scores
        self.name = name

    def get_scores(self):
        return self.scores

    def get_sum(self):
        return sum(self.scores)

    def get_name(self):
        return self.name

然后你可以做类似的事情

user_a = User([1,2,3], "Jerry Stewart")
user_b = User([1,3,12,13,110], "Godric Gryffindor")
user_c = User([8,10,11], "Jackie")
users = [user_a, user_b, user_c]

for user in users:
    print "{} : {}".format(user.get_name(), user.get_sum())

希望这涵盖了您需要的基础知识!

【讨论】:

  • 谢谢你,这很有帮助!我不知道这个格式函数,所以我学到的比我要求的还要多!
  • 我真的很高兴有帮助!字符串的格式化方法非常有用!如果您还没有找到完整的文档here
【解决方案2】:

欢迎来到 SO!

基于 Hallsville3 的回答,我认为您可以通过简单地对列表进行子类化来实现类似的结果,如下所示:

class User(list):
    def __init__(self, name, scores):
        super().__init__(scores)
        #Where scores is a list of their scores. This assumes you are using Python 3. Super calls in python 2 need a couple more arguments.
        self.name = name

然后您可以创建用户列表并轻松添加到其中:

user_base = []
user_base.append(User('Stuart', [1, 2, 3]))
user_base.append(User('Jane', [4, 5, 6]))

此数据模型只有两层 Userlist => Scorelist/User Object,而不是 Userlist => User Object => Scorelist,这应该会使访问它稍微简单一些。

您还可以扩展对象以返回每个用户的统计信息:

class User(list):
    def __init__(self, name, scores):
        super().__init__(scores)
        self.name = name
    @property
    def average(self):
        return sum(self)/len(self)

并使用它返回所有用户的平均值:

[user.average for user in user_base]

实际上有数以千计的方法来构建您的数据,从像这样的简单实现到 SQL 数据库(如果您要大规模执行此操作)。我认为从一个简单的模型开始,然后随着技能的提高逐渐增加复杂性是有意义的。

祝你好运!

【讨论】:

    【解决方案3】:

    您可以使用Dictionary,因为字典中的值可以是mutable,例如list,您可以在其中保留每个用户的所有分数/获胜分数。

    {'player1' : [22,33,44,55], 'player2' : [23,34,45], ..... }

    如果这不是一个你会重复的练习,那么 dicts 是有意义的,但如果它是一个未来可能需要再次完成的练习,Classes 是更好的选择,正如 Stuart 和 Hallsville3 在其他答案中所解释的那样。

    希望对你有帮助!

    【讨论】:

      【解决方案4】:

      由于已经有一个涵盖类选项的答案,因此我给出了我能想到的最简单的基于字典的解决方案。 我个人更喜欢先使用简单的字典方法,如果需要,以后可能会切换到更灵活的类实现。

      一个基本的分数字典及其用法可能如下所示:

      scores = {}
      
      scores["user1"] = []  # empty scores list
      scores["user2"] = [14, 32, 67]
      scores["user3"] = [1, 94]
      
      scores["user1"].append(45)  # add a single score
      scores["user3"].extend([13, 22])  # add multiple scores
      
      for user, user_scores in scores.items():
          print(user, user_scores, min(user_scores), max(user_scores), sum(user_scores))
      

      输出如下所示:

      user1 [45] 45 45 45
      user2 [14, 32, 67] 14 67 113
      user3 [1, 94, 13, 22] 1 94 130
      

      也许您可以尝试这种方法,看看它是否符合您的需求。

      【讨论】:

      • 是的,这个补充非常有帮助,谢谢!你让我意识到一些事情;我最多只能想象少数用户的场景。但不应该有这样的限制。如果我可能会用另一个问题来麻烦您:如果您有一个包含 100 个用户的列表,那么最佳做法是什么?那么创建字典会更好吗?在我看来,我想为每个用户创建一个类实例会占用大量内存,但这可能只是因为类的代码看起来与字典相比效率较低。
      • 我认为当您尝试优化某些东西时,您必须像往常一样尝试和衡量。一百个用户应该不是问题。即使对于拥有数千个分数的数百万用户来说,字典也非常好。还有一种方法可以使用slots 来实现内存效率更高的类,但我不知道它与内存使用中的普通字典方法相比如何。我会首先争取最简单的解决方案,只有在遇到真正的内存问题时才进行优化。
      【解决方案5】:
      当同时存在 state 和 behavior 时使用

      class。只有状态时使用 dict 。因为你们都有使用类。

      【讨论】:

        【解决方案6】:

        根据您的描述,您只需要 defaultdictlist 作为默认值。

        from collections import defaultdict
        
        scores = defaultdict(list)
        scores['User1'].append(3)
        scores['User1'].append(5)
        scores['User2'].append(6)
        scores['User2'].append(1)
        
        print(scores)
        # defaultdict(<class 'list'>, {'User1': [3, 5], 'User2': [6, 1]})
        
        print(sorted(scores, key= lambda k: sum(scores[k]), reverse=True))
        # ['User1', 'User2']
        
        print(sorted(scores, key= lambda k: sum(scores[k])/len(scores[k]), reverse=True))
        # ['User1', 'User2']
        

        如果每个用户只有一个分数,您可以使用Counter

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2018-11-13
          • 1970-01-01
          • 1970-01-01
          • 2021-09-29
          • 2011-05-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多