【问题标题】:cPickle saved object loaded modified - PythoncPickle 保存的对象已加载修改 - Python
【发布时间】:2014-11-02 12:08:02
【问题描述】:

在我的脚本中,我尝试使用 cPickle 保存字典。一切正常,除了加载字典已修改每个键。 我的字典看起来像:{'a':[45,155856,26,98536], 'b':[88,68,9454,78,4125,52]...}

当我在保存之前从该字典中打印键时,它会打印正确的值:'a','b'...

但是当我保存它然后使用 cPickle 加载时,每个键在正确的字符后包含'\r''a\r','b\r'...

这是保存的代码:

def saveSuffixArrayDictA():
        for i in self.creation.dictA.keys():
            print len(i)
        print 'STOP'
        with open('dictA','w+') as f:
            pickle.dump(self.creation.dictA,f)

哪个打印:1,1,1,1,1,1....STOP(当然是换行符)

然后,当我尝试使用此加载它时:

@staticmethod
def dictA():
    with open('ddictA','rb') as f:
        dict = pickle.load(f)
    for i in dict.keys():
        print len(i)
    print 'STOP'
    return dict

它返回:2,2,2,2,2,2,2,2...STOP(当然还有换行符)

如您所见,它应该是相同的,但它不是...请问问题出在哪里?

编辑:我尝试打印值并意识到列表中的每个项目(列表是值)都在该项目的末尾添加了“L”,这是一个数字。

【问题讨论】:

  • 如果将写入模式从w+ 更改为wb+ 会发生什么? (由于w+ 是一种文本模式,在Windows 上它会将\n 映射到\r\n。)
  • @unutbu 谢谢你的帮助!现在,它可以正常工作了。

标签: python dictionary pickle


【解决方案1】:

the docs:

确保始终以二进制格式打开使用协议 >= 1 创建的 pickle 文件 模式。对于旧的基于 ASCII 的 pickle 协议 0,您可以使用任一文本模式 或二进制模式只要您保持一致。 (我的重点)

因此,不要以文本模式w+写入pickle文件,而是以二进制模式rb读取。 相反,请使用二进制模式,wb+rb


When you write in text mode(例如w+),\n 映射到特定于操作系统的行尾字符。在 Windows 上,\n 映射到 \r\n。这似乎是键中出现错误\rs 的来源。

【讨论】:

    【解决方案2】:

    这是一个非常奇怪的错误,我不知道它的原因。但这是在 python 中保存和加载数据结构的另一种方法。只需使用str() 将您的数据结构转换为字符串并将其写入任何file。将file 加载回来,在任何变量中读取它并使用ast 将其转换回数据结构。 Demo如下:

    >>> import ast
    >>> d={'a':[1,2,3,4],'b':[5,6,7,8],'c':[9,10]}
    >>> saveDic=str(d)
    >>> saveDic
    "{'a': [1, 2, 3, 4], 'c': [9, 10], 'b': [5, 6, 7, 8]}"
    # save this string to any file, load it back and convert to dictionary using ast
    >>> d=ast.literal_eval(saveDic)
    >>> d
    {'a': [1, 2, 3, 4], 'c': [9, 10], 'b': [5, 6, 7, 8]}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多