漬物ファイルにリストを追加するのに苦労しています。これはコードです:
#saving high scores to a pickled file
import pickle
first_name = input("Please enter your name:")
score = input("Please enter your score:")
scores = []
high_scores = first_name, score
scores.append(high_scores)
file = open("high_scores.dat", "ab")
pickle.dump(scores, file)
file.close()
file = open("high_scores.dat", "rb")
scores = pickle.load(file)
print(scores)
file.close()
初めてコードを実行すると、名前とスコアが出力されます。
2回目にコードを実行すると、2つの名前と2つのスコアが出力されます。
3回目にコードを実行すると、名とスコアが出力されますが、2番目の名前とスコアは、入力した3番目の名前とスコアで上書きされます。名前とスコアを追加し続けたいだけです。最初の名前が保存され、2番目の名前が上書きされる理由がわかりません。
リストに追加する前に、まずデータベース(つまりピクルファイル)からリストをプルする必要があります。
import pickle
import os
high_scores_filename = 'high_scores.dat'
scores = []
# first time you run this, "high_scores.dat" won't exist
# so we need to check for its existence before we load
# our "database"
if os.path.exists(high_scores_filename):
# "with" statements are very handy for opening files.
with open(high_scores_filename,'rb') as rfp:
scores = pickle.load(rfp)
# Notice that there's no "rfp.close()"
# ... the "with" clause calls close() automatically!
first_name = input("Please enter your name:")
score = input("Please enter your score:")
high_scores = first_name, score
scores.append(high_scores)
# Now we "sync" our database
with open(high_scores_filename,'wb') as wfp:
pickle.dump(scores, wfp)
# Re-load our database
with open(high_scores_filename,'rb') as rfp:
scores = pickle.load(rfp)
print(scores)
Pickle化されたファイルに読み書きしたい場合は、リストの各エントリに対してdumpを複数回呼び出すことができます。ダンプするたびに、ピクルス化したファイルにスコアを追加し、ロードするたびに次のスコアを読み取ります。
>>> import pickle as dill
>>>
>>> scores = [('joe', 1), ('bill', 2), ('betty', 100)]
>>> nscores = len(scores)
>>>
>>> with open('high.pkl', 'ab') as f:
… _ = [dill.dump(score, f) for score in scores]
...
>>>
>>> with open('high.pkl', 'ab') as f:
... dill.dump(('mary', 1000), f)
...
>>> # we added a score on the fly, so load nscores+1
>>> with open('high.pkl', 'rb') as f:
... _scores = [dill.load(f) for i in range(nscores + 1)]
...
>>> _scores
[('joe', 1), ('bill', 2), ('betty', 100), ('mary', 1000)]
>>>
コードが失敗する可能性が最も高いのは、元のscores
を、ピックされていないスコアのリストに置き換えるためです。そのため、新しいスコアが追加された場合は、それらをメモリに爆破します。
>>> scores
[('joe', 1), ('bill', 2), ('betty', 100)]
>>> f = open('high.pkl', 'wb')
>>> dill.dump(scores, f)
>>> f.close()
>>>
>>> scores.append(('mary',1000))
>>> scores
[('joe', 1), ('bill', 2), ('betty', 100), ('mary', 1000)]
>>>
>>> f = open('high.pkl', 'rb')
>>> _scores = dill.load(f)
>>> f.close()
>>> _scores
[('joe', 1), ('bill', 2), ('betty', 100)]
>>> blow away the old scores list, by pointing to _scores
>>> scores = _scores
>>> scores
[('joe', 1), ('bill', 2), ('betty', 100)]
したがって、これはscores
の問題というよりは、pickle
のpythonの名前参照の問題に近いものです。 Pickle
は、新しいリストをインスタンス化してscores
(あなたの場合)と呼んでいるだけであり、その前にscores
が指し示していたものをガベージコレクションします。
>>> scores = 1
>>> f = open('high.pkl', 'rb')
>>> scores = dill.load(f)
>>> f.close()
>>> scores
[('joe', 1), ('bill', 2), ('betty', 100)]
実際には質問に答えませんが、誰かが一度に1つのアイテムをピクルスに追加したい場合は、次の方法で行うことができます...
import pickle
import os
high_scores_filename = '/home/ubuntu-dev/Desktop/delete/high_scores.dat'
scores = []
# first time you run this, "high_scores.dat" won't exist
# so we need to check for its existence before we load
# our "database"
if os.path.exists(high_scores_filename):
# "with" statements are very handy for opening files.
with open(high_scores_filename,'rb') as rfp:
scores = pickle.load(rfp)
# Notice that there's no "rfp.close()"
# ... the "with" clause calls close() automatically!
names = ["mike", "bob", "joe"]
for name in names:
high_score = name
print(name)
scores.append(high_score)
# Now we "sync" our database
with open(high_scores_filename,'wb') as wfp:
pickle.dump(scores, wfp)
# Re-load our database
with open(high_scores_filename,'rb') as rfp:
scores = pickle.load(rfp)
print(scores)
Pickleを使用せず、目的を解決するh5pyを使用する
with h5py.File('.\PreprocessedData.h5', 'a') as hf:
hf["X_train"].resize((hf["X_train"].shape[0] + X_train_data.shape[0]), axis = 0)
hf["X_train"][-X_train_data.shape[0]:] = X_train_data
hf["X_test"].resize((hf["X_test"].shape[0] + X_test_data.shape[0]), axis = 0)
hf["X_test"][-X_test_data.shape[0]:] = X_test_data
hf["Y_train"].resize((hf["Y_train"].shape[0] + Y_train_data.shape[0]), axis = 0)
hf["Y_train"][-Y_train_data.shape[0]:] = Y_train_data
hf["Y_test"].resize((hf["Y_test"].shape[0] + Y_test_data.shape[0]), axis = 0)
hf["Y_test"][-Y_test_data.shape[0]:] = Y_test_data