1

我正在尝试:

  • 加载字典
  • 更新/更改字典
  • 节省
  • (重复)

问题:我只想使用 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)
4

2 回答 2

1

您正在擦除您的更改;而不是写出你的文件,你重新阅读它,结果被用来替换你的players_scores字典。在那之前你defaultdict工作得很好,即使你不能在这里真正使用defaultdictast.literal_eval()支持,只有标准的 python 文字 dict 表示法)。collections.defaultdict

您可以通过使用此处的json模块来简化代码:

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这里;无论如何,您只是为每个玩家名称创建新字典。

于 2013-04-26T21:15:58.210 回答
1

我认为一个问题是要以您想要的方式索引数据结构,真正需要的是像 a 这样的东西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)
于 2013-04-27T00:14:19.437 回答