初学者python。为每个键存储不同数量的项目的最佳方法?
Beginners python. Best way to store different amount of items for each key?
我是编程的新手(也是一个老手),所以我真的不知道如何正确表达我想要的东西。我已尝试尽可能详尽地描述我的问题,非常感谢您的耐心等待!
我想存储与每个用户关联的获胜分数。
- 每个用户会有不同的中奖分数。
- 我不需要将用户的名字和姓氏分开,它们可以是一个字符串。
- 我不需要以任何方式排序分数,也不需要能够更改它们。
- 我只需要能够在用户获胜时添加分数并按获胜数量对用户进行排序。
- 我会把所有的中奖分数都提取出来统计,但是统计不会关心什么分数属于什么用户。
- 一旦程序停止,它可以从内存中全部删除。
根据我目前的研究,我最好的选择似乎是创建一个用户 class,我在其中存储一个列表并每次都添加到列表中。或者为每个用户创建一个带有键的字典。但是由于每个用户可能有不同数量的获胜分数,我不知道我是否可以使用字典(除非每个键可能与一个列表相关联?)。我不认为我需要像 numpy 数组这样的东西,因为我想创建非常简单的统计数据而不用担心什么分数属于什么用户。
我需要考虑不要使用不必要的内存等,特别是因为每个用户可能有一百个获胜分数。但是我真的找不到关于字典与 classes 的好处的明确信息。编程社区非常有帮助并且充满了答案,但不幸的是我经常不理解答案。
非常感谢我能得到的任何帮助!不要害怕告诉我我的想法很愚蠢,我想学习如何像程序员一样思考。
这是一个很好的问题,因为它讨论了两种可能的解决方案。基于 class 的解决方案和基于字典的解决方案。基于 class 的解决方案更加优雅和通用,所以我将描述那个。
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())
希望这涵盖了您所需要的基础知识!
欢迎来到 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 对象,而不是 Userlist => User Object => Scorelist,这样访问起来会稍微简单一些。
您还可以将对象扩展为 return 每个用户的统计信息:
class User(list):
def __init__(self, name, scores):
super().__init__(scores)
self.name = name
@property
def average(self):
return sum(self)/len(self)
并用它来 return 所有用户的平均值:
[user.average for user in user_base]
从字面上看,有数千种构建数据的方法,从像这样的简单实现到 SQL 数据库(如果您要大规模执行此操作)。我认为从一个简单的模型开始,然后随着你的技能的积累而增加复杂性是有意义的。
祝你好运!
因为已经有涵盖 class 选项的答案,我给出了我能想到的最简单的基于字典的解决方案。
我个人更愿意先使用简单的字典方法,如果需要的话,以后可能会切换到更灵活的 class 实现。
基本乐谱字典及其用法可能如下所示:
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
也许您可以尝试一下这种方法,看看它是否符合您的需要。
class用于同时存在状态和行为的情况。当只有状态时使用字典。因为你们都使用 class。
根据您的描述,您只需要 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
。
您可以使用 Dictionary
,因为字典中的值可以是 mutable
,就像 list
,您可以在其中保留每个用户的所有 scores/winning 分数。
{'player1' : [22,33,44,55],
'player2' : [23,34,45],
.....
}
如果这不是一个你会重复的练习,那么听写是有意义的,但如果它是一个可能需要在未来再次做的练习,Classes
是更好的选择,正如 Stuart 和 Hallsville3 在其他答案中所解释的那样.
希望对您有所帮助!
我是编程的新手(也是一个老手),所以我真的不知道如何正确表达我想要的东西。我已尝试尽可能详尽地描述我的问题,非常感谢您的耐心等待!
我想存储与每个用户关联的获胜分数。
- 每个用户会有不同的中奖分数。
- 我不需要将用户的名字和姓氏分开,它们可以是一个字符串。
- 我不需要以任何方式排序分数,也不需要能够更改它们。
- 我只需要能够在用户获胜时添加分数并按获胜数量对用户进行排序。
- 我会把所有的中奖分数都提取出来统计,但是统计不会关心什么分数属于什么用户。
- 一旦程序停止,它可以从内存中全部删除。
根据我目前的研究,我最好的选择似乎是创建一个用户 class,我在其中存储一个列表并每次都添加到列表中。或者为每个用户创建一个带有键的字典。但是由于每个用户可能有不同数量的获胜分数,我不知道我是否可以使用字典(除非每个键可能与一个列表相关联?)。我不认为我需要像 numpy 数组这样的东西,因为我想创建非常简单的统计数据而不用担心什么分数属于什么用户。 我需要考虑不要使用不必要的内存等,特别是因为每个用户可能有一百个获胜分数。但是我真的找不到关于字典与 classes 的好处的明确信息。编程社区非常有帮助并且充满了答案,但不幸的是我经常不理解答案。
非常感谢我能得到的任何帮助!不要害怕告诉我我的想法很愚蠢,我想学习如何像程序员一样思考。
这是一个很好的问题,因为它讨论了两种可能的解决方案。基于 class 的解决方案和基于字典的解决方案。基于 class 的解决方案更加优雅和通用,所以我将描述那个。
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())
希望这涵盖了您所需要的基础知识!
欢迎来到 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 对象,而不是 Userlist => User Object => Scorelist,这样访问起来会稍微简单一些。
您还可以将对象扩展为 return 每个用户的统计信息:
class User(list):
def __init__(self, name, scores):
super().__init__(scores)
self.name = name
@property
def average(self):
return sum(self)/len(self)
并用它来 return 所有用户的平均值:
[user.average for user in user_base]
从字面上看,有数千种构建数据的方法,从像这样的简单实现到 SQL 数据库(如果您要大规模执行此操作)。我认为从一个简单的模型开始,然后随着你的技能的积累而增加复杂性是有意义的。
祝你好运!
因为已经有涵盖 class 选项的答案,我给出了我能想到的最简单的基于字典的解决方案。 我个人更愿意先使用简单的字典方法,如果需要的话,以后可能会切换到更灵活的 class 实现。
基本乐谱字典及其用法可能如下所示:
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
也许您可以尝试一下这种方法,看看它是否符合您的需要。
class用于同时存在状态和行为的情况。当只有状态时使用字典。因为你们都使用 class。
根据您的描述,您只需要 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
。
您可以使用 Dictionary
,因为字典中的值可以是 mutable
,就像 list
,您可以在其中保留每个用户的所有 scores/winning 分数。
{'player1' : [22,33,44,55],
'player2' : [23,34,45],
.....
}
如果这不是一个你会重复的练习,那么听写是有意义的,但如果它是一个可能需要在未来再次做的练习,Classes
是更好的选择,正如 Stuart 和 Hallsville3 在其他答案中所解释的那样.
希望对您有所帮助!