【问题标题】:Store a dictionary in a file for later retrieval将字典存储在文件中以供以后检索
【发布时间】:2013-06-23 17:20:00
【问题描述】:

我已经四处搜索,但找不到任何关于此的信息...

我正在寻找一种将字典保存到文件中的方法,然后能够在以后通过读取文件将其加载回变量中。

文件的内容不必是“人类可读的”,它可以随心所欲。

谢谢 - 海福克斯

编辑

import cPickle as pickle

BDICT = {}

## Automatically generated START
name = "BOB"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TOM"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TIMMY JOE"
name_title = name.title()
count = 5
BDICT[name_title] = count
## Automatically generated END

if BDICT:
    with open('DICT_ITEMS.txt', 'wb') as dict_items_save:
        pickle.dump(BDICT, dict_items_save)

BDICT = {} ## Wiping the dictionary

## Usually in a loop
firstrunDICT = True

if firstrunDICT:
    with open('DICT_ITEMS.txt', 'rb') as dict_items_open:
        dict_items_read = dict_items_open.read()
        if dict_items_read:
            BDICT = pickle.load(dict_items_open)
            firstrunDICT = False
            print BDICT

错误:

Traceback (most recent call last):
  File "C:\test3.py", line 35, in <module>
    BDICT = pickle.load(dict_items_open)
EOFError

【问题讨论】:

  • 你能在BTS_DICT周围加上几行吗?您已经使用 BDICT 加载了腌制对象,然后您尝试再次执行此操作 - BTS_DICT 在您的上下文管理器之外 (with open()...)?

标签: python python-2.7 dictionary load store


【解决方案1】:

有几个人推荐了shelve——我没用过,也不敲了。我使用过pickle/cPickle,我将提供以下方法:

Pickle/cPickle的使用方法(精简版)...

许多原因让您使用 Pickle(或其明显更快的变体 cPickle)。简而言之,Pickle 是一种在进程之外存储对象的方法。

Pickle 不仅为您提供了在 python 进程之外存储对象的选项,而且还以序列化的方式进行。意思是,先进先出行为(FIFO)。

import pickle

## I am making up a dictionary here to show you how this works...
## Because I want to store this outside of this single run, it could be that this
## dictionary is dynamic and user based - so persistance beyond this run has
## meaning for me.  
myMadeUpDictionary = {"one": "banana", "two": "banana", "three": "banana", "four": "no-more"}

with open("mySavedDict.txt", "wb") as myFile:
    pickle.dump(myMadeUpDictionary, myFile)

那么刚刚发生了什么?

  • 第一步:导入一个名为“pickle”的模块
  • 第二步:创建我的字典对象
  • Step3:使用context manager 处理新文件的打开/关闭...
  • 第 4 步:dump() 字典的内容(被称为“腌制”对象),然后将其写入文件 (mySavedDict.txt)。

如果您随后进入刚刚创建的文件(现在位于您的文件系统上),您可以看到内容。它很凌乱-丑陋-而且不是很有洞察力。

nammer@crunchyQA:~/workspace/SandBox/POSTS/Pickle & cPickle$ cat mySavedDict.txt 
(dp0
S'four'
p1
S'no-more'
p2
sS'three'
p3
S'banana'
p4
sS'two'
p5
g4
sS'one'
p6
g4
s.

那么接下来呢?

要将它带回到我们的程序中,我们只需执行以下操作:

import pickle

with open("mySavedDict.txt", "rb") as myFile:
    myNewPulledInDictionary = pickle.load(myFile)

print myNewPulledInDictionary

提供以下回报:

{'four': 'no-more', 'one': 'banana', 'three': 'banana', 'two': 'banana'}

cPickle 与 Pickle

这些天你不会看到很多人使用 pickle - 我无法想到你为什么要使用 pickle 的第一个实现,特别是当有 cPickle 做同样的事情时(更多或更少)但要快得多!

所以你可以偷懒做:

import cPickle as pickle

如果您已经构建了使用 pickle 的东西,那就太好了...但是 我认为这是一个糟糕的建议,我完全希望即使推荐它也会受到责骂!(你真的应该查看使用原始 pickle 的旧实现,看看是否需要更改任何内容以遵循 cPickle 模式;如果您有遗留代码或正在使用的生产代码,这可以节省重构时间(查找/替换所有使用 cPickle 的 pickle 实例)。

否则,只需:

import cPickle

在您看到对pickle 库的引用的任何地方,只需相应地替换即可。它们具有相同的 load() 和 dump() 方法。

警告警告我不想再写这篇文章了,但我似乎有一种痛苦的记忆,没有区分load()loads(),并且dump()dumps()。该死的……那是我的愚蠢!简短的回答是 load()/dump() 对类似文件的对象执行此操作,其中 load()/dumps() 将执行类似的行为,但对类似字符串的对象执行类似的行为(在 API 中阅读有关它的更多信息,@ 987654322@)。

再说一次,我还没有使用过shelve,但如果它对你(或其他人)有用,那就太好了!

回复您的编辑

最后,您需要从上下文管理器中删除 dict_items_read = dict_items_open.read()。该文件已经打开并读入。您不会像读取文本文件那样读取它来提取字符串......它正在存储腌制的python对象。不是为了眼睛!它适用于 load()。

您的代码已修改...对我来说效果很好(复制/粘贴并运行下面的代码,看看它是否有效)。请注意,在底部附近,我删除了文件对象的 read()

import cPickle as pickle

BDICT = {}

## Automatically generated START
name = "BOB"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TOM"
name_title = name.title()
count = 5
BDICT[name_title] = count

name = "TIMMY JOE"
name_title = name.title()
count = 5
BDICT[name_title] = count
## Automatically generated END

if BDICT:
    with open('DICT_ITEMS.txt', 'wb') as dict_items_save:
        pickle.dump(BDICT, dict_items_save)

BDICT = {} ## Wiping the dictionary

## Usually in a loop
firstrunDICT = True

if firstrunDICT:
    with open('DICT_ITEMS.txt', 'rb') as dict_items_open:
        BDICT = pickle.load(dict_items_open)
        firstrunDICT = False
        print BDICT

【讨论】:

  • 我已经重新编辑了我的主要主题,以获取我的代码示例,该示例导致错误......我该如何解决它?
  • 见上文“对您的编辑的回应”并记住选择最能解决您的问题的答案。 (在最能回答您的问题的答案标题旁边打一个绿色复选标记)。
  • @Hyflex,不错。过失。我在没有用 Python 测试的情况下对 SO 进行了编辑。我已经编辑了坏行(删除了dict_items_read 的真实性,所以它永远不会评估。我复制/粘贴了这段代码,它测试良好。
  • 但是,对于 Python 3+,仅使用 pickle : stackoverflow.com/a/37138791/2306662(我同意 2.7 标签,但这是为其他在搜索 Python 3+ 答案时最终来到这里的人具体)
【解决方案2】:

Python为此提供了shelve 模块。它可以将许多对象存储在一个文件中,以后可以打开并作为对象读入,但它依赖于操作系统。

import shelve

dict1 = #dictionary
dict2 = #dictionary

#flags: 
#   c = create new shelf; this can't overwrite an old one, so delete the old one first
#   r = read
#   w = write; you can append to an old shelf
shelf = shelve.open("filename", flag="c")
shelf['key1'] = dict1
shelf['key2'] = dict2

shelf.close()

#reading:
shelf = shelve.open("filename", flag='r')
for key in shelf.keys():
    newdict = shelf[key]
    #do something with it

shelf.close()

【讨论】:

    【解决方案3】:

    您也可以使用Pickle 执行此任务。 Here's a blog post 解释了如何做到这一点。

    【讨论】:

    • pickle 是完成这项工作的完美工具。我只建议导入cPickle as pickle 以获得更好的性能(和相同的功能集),并将pickle.HIGHEST_PROTOCOL 传递给转储。 (它默认使用旧的 7 位协议以确保向前兼容。)
    • 同意。话虽如此,我还没有使用 shelve,但我立即想到了 cPickle 来完成这项工作。致 OP:仅供参考,值得快速阅读 (stackoverflow.com/questions/8514020/…)。
    • @Nascent_Notes 如果您看到我在这个问题中的第一篇文章,我已经编辑以显示示例代码和我收到的错误:/ 任何想法吗?
    • @Hyflex,您是否正在加载以前“腌制”的对象?您不能只读取您放入文件中的任何旧内容。您需要构建您的对象,然后将其腌制到一个文件中,然后您可以重新加载它。您可以粘贴您的代码以便我可以看到更多您在做什么吗?
    • @Nascent_Notes 我将字典腌制在不同的文件中,挑选的文件内容是:(dp0 S'Bob' p1 I2 sS'Tom' p2 I2 sS'Jimmy' p3 I3 s.
    【解决方案4】:

    你要找的是shelve

    【讨论】:

    • 我认为这是相当于列表的泡菜库的字典?
    • @Hyflex 不是真的。 pickle 也用于字典。它是一个适用于任何 python 对象的序列化库。搁板只是泡菜上方的一个方便层,尤其是在存放许多物体时。在你的情况下,泡菜可能就足够了,但使用搁置没有害处。
    • 您能详细说明一下吗? -1 直到有比单个链接更多的描述。
    【解决方案5】:

    创建文本文件以保存字典和加载字典(之前已保存)以供再次使用的两个函数。

    import pickle
    
    def SaveDictionary(dictionary,File):
        with open(File, "wb") as myFile:
            pickle.dump(dictionary, myFile)
            myFile.close()
    
    def LoadDictionary(File):
        with open(File, "rb") as myFile:
            dict = pickle.load(myFile)
            myFile.close()
            return dict
    

    这些函数可以通过:

    SaveDictionary(mylib.Members,"members.txt") # saved dict. in a file
    members = LoadDictionary("members.txt")     # opened dict. of members
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      • 1970-01-01
      • 1970-01-01
      • 2021-08-24
      相关资源
      最近更新 更多