2017-10-06 98 views
1

我是編程初學者(也是老年人),所以我不知道如何正確表達我想要的東西。我試圖儘可能徹底地描述我的問題,所以非常感謝您的耐心!初學者python。爲每個鍵存儲不同數量的項目的最佳方法是什麼?

我想存儲與每個用戶關聯的獲勝分數。

  • 每個用戶將有不同數量的獲勝分數。
  • 我不需要分隔用戶的名字和姓氏,他們都可以是一個字符串。
  • 我不需要以任何方式訂購分數,我也不需要能夠改變它們。
  • 我只需要能夠添加分數,只要用戶贏得勝利和排序的用戶。
  • 我會提取統計數據的所有獲勝分數,但統計數據不會涉及屬於哪個用戶的分數。
  • 一旦程序停止,它可以全部從內存中刪除。

從我到目前爲止研究過的看來,我最好的選擇是創建一個用戶類,在那裏存儲一個列表並每次添加到列表中。或者爲每個用戶創建一個帶有密鑰的字典。但是由於每個用戶可能有不同的獲勝分數,我不知道是否可以使用字典(除非每個鍵都與一個列表關聯)。我不認爲我需要像numpy數組這樣的東西,因爲我想創建非常簡單的統計數據,而不必擔心屬於哪個用戶的分數。 我需要考慮不要使用不必要的內存量等,尤其是因爲每個用戶可能有一百個獲勝分數。但是我無法真正找到有關字典和類的好處的明確信息。編程社區是非常有幫助和充滿答案的,但不幸的是我經常不理解答案。

偉大的任何幫助,我可以得到!不要害怕告訴我,我的想法是愚蠢的,我想學習如何像程序員一樣思考。

+0

使用帶有列表值的字典沒有問題。字典實際上在python中非常高效,並且在「在hod之下」(也在類中)處處使用。我的第一個方法是使用一個普通的字典,分數列表作爲值。如果您以後需要更多靈活性,則可以使用其他功能切換到自定義類。也許你會發現這個[視頻](https://www.youtube.com/watch?v=npw4s1QTmPg)關於這個話題有趣。 – Lukisn

回答

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

希望這涵蓋了你所需要的基本知識!

+0

非常感謝您的幫助!我不知道這種格式的功能,所以我學到的東西甚至超過了我的要求! – kritters

+0

我真的很高興幫助! Strings的格式化方法非常有用!如果你還沒有找到完整的文檔[這裏](https://docs.python.org/2/library/string.html#format-examples) – Hallsville3

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 => 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數據庫,如果你正在做這個大規模。我認爲從一個簡單的模型開始,然後在建立技能時增加複雜性是有道理的。

祝你好運!

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 

也許你可以用這種方法進行實驗,看看它是否適合您的需求。

+0

是的,這個補充是非常有用的,謝謝!你讓我意識到了一些事情;我只是想象一個少數用戶的場景。但是不應該有這樣的限制。如果我可能會給另一個問題帶來麻煩:如果您有一百個用戶的列表,最佳做法是什麼?那麼創建一本字典是否更好?在我看來,我想象爲每個用戶創建一個類實例會佔用大量內存,但也許這只是因爲類_looks_的代碼與字典相比效率較低。 – kritters

+0

我認爲你必須嘗試像往常一樣測量,當你嘗試優化一些東西。一百個用戶不應該是一個問題。即使是數以百萬計的用戶,字典也是完美無瑕的。還有一種方法可以使用[__slots__](https://docs.python.org/3/reference/datamodel.html#slots)實現更多的高效內存類,但我不知道它如何與普通字典方法相比較在內存使用中。我會首先爭取最簡單的解決方案,並只在存在真正的內存問題時才進行優化。 – Lukisn

0

當有狀態和行爲時,使用類。當只有狀態時才使用字典。因爲你們都使用課堂。

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

1

您可以使用Dictionary,因爲在詞典中的值可以是mutable,比如list,您可以在其中保存每個用戶的所有分數/獲勝分數。

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

如果這不是一個練習,你會重複類型的字典意義,但如果它是一個可能需要再次在未來Classes做的運動是更好的選擇,因爲在由Stuart和Hallsville3其他答案解釋。

希望它有幫助!

相關問題