1

私はしようとしています:

  • 辞書を読み込む
  • 辞書を更新/変更する
  • 保存
  • (繰り返す)

問題: 1 つのディクショナリ (players_scores) だけで作業したいのですが、defaultdict 式は完全に別のディクショナリを作成します。1 つの辞書をロード、更新、および保存するにはどうすればよいですか?

コード:

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

問題の 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()、関数がサポートする単純なリテラル データ型の 1 つではないため、文字列表現に変換されたものでは機能しません。pickle代わりに、私が説明しているようなカスタム クラスと同様に、Python の組み込みデータ型のほとんどを処理できる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 に答える
1

変更を消去しています。ファイルを書き出す代わりに、ファイルを新たに読み取り、結果を使用して辞書を置き換えます。ここで実際に使用できない場合でも、それ以前は問題なく機能していplayers_scoresました(は標準の python リテラル dict 表記のみをサポートしていません)。defaultdictdefaultdictast.literal_eval()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 に答える