初学者蟒蛇。为每个密钥存储不同数量的项目的最佳方法?

时间:2017-10-06 05:44:45

标签: python list dictionary key-value

我是编程的初学者(也是一个老人),所以我真的不知道如何正确表达我想要的东西。我试图尽可能彻底地描述我的问题,所以非常感谢你的耐心!

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

  • 每个用户都有不同数量的获胜分数。
  • 我不需要分隔用户的名字和姓氏,它们都可以是一个字符串。
  • 我不需要以任何方式订购分数,我也不需要能够更改它们。
  • 我只需要能够在用户赢取和按用户数量排序用户时添加分数。
  • 我将提取统计数据的所有获胜分数,但统计数据不关心什么分数属于哪个用户。
  • 一旦程序停止,它就可以从内存中删除。

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

很高兴能得到任何帮助!并且不要害怕告诉我我的想法是愚蠢的,我想学习如何像程序员一样思考。

6 个答案:

答案 0 :(得分: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())

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

答案 1 :(得分:1)

欢迎来到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 =>得分列表/用户对象,而不是Userlist =>用户对象=>得分列表,应该使访问它稍微简单。

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

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数据库。我认为从一个简单的模型开始然后在你建立自己的技能时提高复杂性是有意义的。

祝你好运!

答案 2 :(得分:1)

您可以使用Dictionary作为值,mutable就像list一样,您可以保留每个用户的所有得分/获胜分数。

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

如果这不是一个练习,你会重复说明有意义,但如果这是一个可能需要在将来再次进行的练习Classes是更好的选择,正如Stuart和Hallsville3在其他答案中所解释的那样。 / p>

希望它有所帮助!

答案 3 :(得分:0)

由于已经有一个覆盖类选项的答案,我给出了我能想出的最简单的字典库解决方案。 我个人更愿意首先使用普通字典方法,如果需要,可能会在以后切换到更灵活的类实现。

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

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

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

答案 4 :(得分:0)

当有状态和行为时使用

类。当只有状态时使用dict。因为你们都有使用课程。

答案 5 :(得分:0)

根据您的说明,您只需defaultdict,默认为list

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