31

875228 的更具体的欺骗——Python 中的简单数据存储

我有一个相当大的字典(6 GB),我需要对其进行一些处理。我正在尝试几种文档聚类方法,因此我需要一次将整个内容保存在内存中。我有其他函数可以在这些数据上运行,但内容不会改变。

目前,每次我想到新功能时,我都必须编写它们,然后重新生成字典。我正在寻找一种将这个字典写入文件的方法,这样我就可以将它加载到内存中,而不是重新计算它的所有值。

过于简化它看起来像:{((('word','list'),(1,2),(1,3)),(...)):0.0, ....}

我觉得 python 必须有比我循环遍历一些字符串寻找 : 和 ( 试图将它解析成字典更好的方法。

4

6 回答 6

62

为什么不使用python pickle?Python 有一个很棒的序列化模块,称为 pickle,它非常易于使用。

import cPickle
cPickle.dump(obj, open('save.p', 'wb')) 
obj = cPickle.load(open('save.p', 'rb'))

泡菜有两个缺点:

  • 对于错误或恶意构建的数据,它并不安全。永远不要取消从不受信任或未经身份验证的来源收到的数据。
  • 该格式不是人类可读的。

如果您使用的是 python 2.6,则有一个名为json的内置模块。使用起来就像泡菜一样简单:

import json
encoded = json.dumps(obj)
obj = json.loads(encoded)

Json 格式是人类可读的,与 python 中的字典字符串表示非常相似。并且没有任何像泡菜这样的安全问题。但可能比 cPickle 慢。

于 2009-05-20T22:07:34.350 回答
12

正如其他答案所建议的那样,我会使用shelve, json,或其他任何东西。yaml

shelve特别酷,因为你可以dict在磁盘上并且仍然使用它。值将按需加载。

但是如果你真的想解析 的文本dict,并且它只包含你展示的strings、ints 和s,你可以使用它来解析它。它更安全,因为你不能用它来评估完整的表达式 - 它只适用于ings、numbers、s、s、s、eans 和:tupleast.literal_evalstrtuplelistdictboolNone

>>> import ast
>>> print ast.literal_eval("{12: 'mydict', 14: (1, 2, 3)}")
{12: 'mydict', 14: (1, 2, 3)}
于 2009-05-20T23:12:21.193 回答
4

我建议你使用YAML作为你的文件格式,这样你就可以在光盘上修改它

How does it look:
  - It is indent based
  - It can represent dictionaries and lists
  - It is easy for humans to understand
An example: This block of code is an example of YAML (a dict holding a list and a string)
Full syntax: http://www.yaml.org/refcard.html

要在 python 中获取它,只需 easy_install pyyaml。见http://pyyaml.org/

它带有简单的文件保存/加载功能,我现在不记得了。

于 2009-05-20T22:57:08.667 回答
0

以下是一些替代方案,具体取决于您的要求:

  • numpy以紧凑的形式存储您的纯数据并很好地执行组/大规模操作

  • shelve就像一个文件备份的大字典

  • 一些第 3 方存储模块,例如stash,存储任意纯数据

  • 适当的数据库,例如用于多毛数据的 mongodb 或 mysql 或 sqlite 纯数据和更快的检索

于 2012-11-05T15:15:06.907 回答
0

以序列化格式写出来,例如pickle(一个用于序列化的python标准库模块)或者可能使用JSON(这是一种可以被评估以再次产生内存表示的表示)。

于 2009-05-20T22:27:09.380 回答
0

SourceForge 的此解决方案仅使用标准 Python 模块:

y_serial.py 模块 :: 使用 SQLite 存储 Python 对象

“序列化 + 持久性 :: 在几行代码中,将 Python 对象压缩和注释为 SQLite;然后在没有任何 SQL 的情况下通过关键字按时间顺序检索它们。数据库存储无模式数据的最有用的“标准”模块。”

http://yserial.sourceforge.net

压缩奖励可能会将您的 6GB 字典减少到 1GB。如果您不想存储一系列字典,该模块还包含一个 file.gz 解决方案,考虑到您的字典大小,它可能更适合。

于 2009-10-02T23:20:55.037 回答