Python-附加到pickle列表
我正在努力将列表附加到一个已修改的文件中。 代码如下:Python-附加到pickle列表,python,append,pickle,Python,Append,Pickle,我正在努力将列表附加到一个已修改的文件中。 代码如下: #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 =
#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个分数
第三次运行代码时,它会打印第一个名称和分数,但会用我输入的第三个名称和分数覆盖第二个名称和分数。我只想让它继续添加名字和分数。我不明白为什么它会保存第一个名字而覆盖第二个 在附加到列表之前,需要先从数据库(即pickle文件)中提取列表
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。每次转储时,都会向pickle文件追加一个分数,每次加载时都会读取下一个分数
>>> 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
[('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)]
因此与其说它是一个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)]
实际上并没有回答这个问题,但如果有人想在泡菜中一次添加一个项目,你可以通过
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)
不要用腌菜,但要用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
还感谢您对代码所做的额外解释。@dogwynn:如果您只是加载到一个新变量,为什么要检查该文件是否存在,以避免真正的问题?@MikeMcKerns:我想我不知道如何从一个不存在的文件调用pickle.load。我知道您可以使用DBv2 API模块(例如shelve)实现这一点,但我不知道有一个类似文件的对象(pickle.load需要)可以在“创建”模式下打开(而不创建)。否则,我的目标是拥有一个可以从命令行重复执行的脚本,每次添加一个新的(名称、分数)元组。@Charlie:我的荣幸。在书上看到另一个Python黑客总是很高兴的。:-)@dogwynn:modeab
代替wb
将在文件不存在时创建一个文件,如果文件存在,则追加文件。此外我不是建议您尝试从一个不存在的文件加载
,只是指出OP的问题更一般地是取消与现有列表同名的对象的链接,从而销毁在转储
后对现有列表所做的任何编辑。也感谢您的输入。dogwynn的解决方案非常有效,但会采纳你所说的。为什么pickle-dill在这里?@DheerajMPai:因为我使用dill
而不是pickle
,所以我的解决方案就是这样使用的<代码>pickle
也可以工作,因此我没有编辑代码,而是更改了导入。一切都在挑选dill
在这方面做得更好。@MikeMcKerns lolololAs用帖子的前5个词表示。为什么不使用hickle
或klepto
?它们都是为HDF5提供简单的dump
和load
pickle等效语法而构建的。如果你在我的回答中用hickle替换dill,我相信它应该可以工作,并存储为HDF5。是的,它可以工作。谢谢你的信息。我不知道希克尔的事。