2013-04-26 171 views
1

我試圖:文件IO與defaultdict

  • 負載詞典
  • 更新/更改字典
  • 保存
  • (重複)

問題:我想僅使用1個字典(players_scores) 工作,但defaultdict表達式創建了一個完全獨立的字典。 如何加載,更新並保存到一本字典?

代碼:

from collections import defaultdict#for manipulating dict 
players_scores = defaultdict(dict) 

import ast #module for removing string from dict once it's called back 


a = {} 

open_file = open("scores", "w") 
open_file.write(str(a)) 
open_file.close() 

open_file2 = open("scores") 
open_file2.readlines() 
open_file2.seek(0) 



i = input("Enter new player's name: ").upper() 
players_scores[i]['GOLF'] = 0 
players_scores[i]['MON DEAL'] = 0 
print() 

scores_str = open_file2.read() 
players_scores = ast.literal_eval(scores_str) 
open_file2.close() 
print(players_scores) 
+0

除非*有*,否則不要使用'ast.literal_eval'。相反,使用'json'模塊,它可以很好地滿足您的需求。 'json.dump(fileobj)',然後'json.load(fileobj)'(不需要'.read()'或'.write()')。 – 2013-04-26 21:11:35

回答

1

更改;而不是寫出你的文件,你重新閱讀它,結果用於替換您的players_scores字典。您的defaultdict在此之前工作得很好,即使您在這裏不能真正使用defaultdictast.literal_eval()確實不支持支持collections.defaultdict,只有標準的python文字字典符號)。

您可以通過使用json module這裏簡化代碼:

import json 

try: 
    with open('scores', 'r') as f: 
     player_scores = json.load(f) 
except IOError: 
    # no such file, create an empty dictionary 
    player_scores = {} 

name = input("Enter new player's name: ").upper() 
# create a complete, new dictionary 
players_scores[name] = {'GOLF': 0, 'MON DEAL': 0} 


with open('scores', 'w') as f: 
    json.dump(player_scores, f) 

你不需要defaultdict這裏所有;無論如何,你只是爲每個球員名字創建新的字典。

+0

使用正確的工具進行工作。很好地使用標準庫。 – MikeHunter 2013-04-26 21:59:17

+0

我一直在這個週末工作,我終於明白了!取得進步是一種令人驚異的感覺。謝謝! – eternal44 2013-04-29 08:47:30

1

我認爲一個問題是,按照你想要的方式索引數據結構,像defaultdict(defaultdict(dict))這樣的東西是真正需要的東西 - 但不幸的是,不可能直接指定一個。然而,要解決的是,所有你需要做的就是定義一個簡單的中介工廠函數傳遞到上層defaultdict

from collections import defaultdict 

def defaultdict_factory(*args, **kwargs): 
    """ Create and return a defaultdict(dict). """ 
    return defaultdict(dict, *args, **kwargs) 

然後你可以用players_scores = defaultdict(defaultdict_factory)創建一個。

但是ast.literal_eval()不能用於已轉換爲字符串表示形式的字符串,因爲它不是函數支持的簡單字面數據類型之一。相反,我建議你考慮使用Python的老式pickle模塊,它可以處理大部分Python的內置數據類型以及像我所描述的自定義類。以下是將其應用於代碼的示例(與上面的代碼結合使用):

import pickle 

try: 
    with open('scores', 'rb') as input_file: 
     players_scores = pickle.load(input_file) 
except FileNotFoundError: 
    print('new scores file will be created') 
    players_scores = defaultdict(defaultdict_factory) 

player_name = input("Enter new player's name: ").upper() 
players_scores[player_name]['GOLF'] = 0 
players_scores[player_name]['MON DEAL'] = 0 
# below is a shorter way to do the initialization for a new player 
# players_scores[player_name] = defaultdict_factory({'GOLF': 0, 'MON DEAL': 0}) 

# write new/updated data structure (back) to disk 
with open('scores', 'wb') as output_file: 
    pickle.dump(players_scores, output_file) 

print(players_scores) 
+0

我正在閱讀json和pickle之間的比較,並且找不到鹹菜的有利用途。你對任何情況都比較喜歡json嗎?感謝您的回覆,獲得幫助令人鼓舞。 – eternal44 2013-04-29 08:50:21

+0

@eternal44:'pickle'支持基本的Python類型和大多數用戶定義的類,只需少量或不需要額外的工作,'json'只支持Python內置類型的一小部分但重要的子集。另一方面,它受到許多其他語言的支持,因此更爲跨平臺,因此常常用於Web編程,如果這是一個考慮因素。現在使用'json'也很時髦。 – martineau 2013-04-29 10:51:47