首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Pickle与shelve在Python中存储大型字典

Pickle与shelve在Python中存储大型字典
EN

Stack Overflow用户
提问于 2013-02-03 09:13:58
回答 2查看 19.1K关注 0票数 23

如果我将一个大目录存储为一个pickle文件,那么通过cPickle加载它是否意味着它将被一次全部消耗到内存中?

如果是这样的话,有没有一种跨平台的方式来获得像pickle这样的东西,但访问每个条目在一个条目上只有一个键(即避免将所有字典加载到内存中,而只按名称加载每个条目)?我知道shelve应该做到这一点:不过,它是否像pickle一样可移植?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-03 10:07:02

我知道

应该是这样做的:它像泡菜一样便携吗?

是。shelveThe Python Standard Library的一部分,是用Python语言编写的。

编辑

因此,如果你有一本大字典:

代码语言:javascript
复制
bigd = {'a': 1, 'b':2, # . . .
}

你想把它保存起来,而不是以后把它全部读进去,也不要把它保存成泡菜,最好把它保存为书架,一种磁盘上的字典。

代码语言:javascript
复制
import shelve

myShelve = shelve.open('my.shelve')
myShelve.update(bigd)
myShelve.close()

然后,稍后您可以:

代码语言:javascript
复制
import shelve

myShelve = shelve.open('my.shelve')
value = myShelve['a']
value += 1
myShelve['a'] = value

基本上,您将搁板对象视为字典,但这些项存储在磁盘上(作为单独的泡菜),并根据需要进行读取。

如果您的对象可以存储为属性列表,那么sqlite可能是一个很好的选择。搁板和泡菜很方便,但只能通过Python访问,而sqlite数据库可以从大多数语言读取。

票数 23
EN

Stack Overflow用户

发布于 2015-09-15 21:09:24

如果你想要一个比shelve更健壮的模块,你可以看看kleptoklepto旨在为磁盘或数据库上的平台无关存储提供字典接口,并用于处理大型数据。

在这里,我们首先创建一些存储在磁盘上的酸洗对象。它们使用dir_archive,它为每个文件存储一个对象。

代码语言:javascript
复制
>>> d = dict(zip('abcde',range(5)))
>>> d['f'] = max
>>> d['g'] = lambda x:x**2
>>> 
>>> import klepto
>>> help(klepto.archives.dir_archive)       

>>> print klepto.archives.dir_archive.__new__.__doc__
initialize a dictionary with a file-folder archive backend

    Inputs:
        name: name of the root archive directory [default: memo]
        dict: initial dictionary to seed the archive
        cached: if True, use an in-memory cache interface to the archive
        serialized: if True, pickle file contents; otherwise save python objects
        compression: compression level (0 to 9) [default: 0 (no compression)]
        memmode: access mode for files, one of {None, 'r+', 'r', 'w+', 'c'}
        memsize: approximate size (in MB) of cache for in-memory compression

>>> a = klepto.archives.dir_archive(dict=d)
>>> a
dir_archive('memo', {'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': <function <lambda> at 0x102f562a8>, 'f': <built-in function max>}, cached=True)
>>> a.dump()
>>> del a

现在,数据都在磁盘上,让我们选择要加载到内存中的数据。b是内存中的字典,而b.archive将文件集合映射到字典视图。

代码语言:javascript
复制
>>> b = klepto.archives.dir_archive('memo')
>>> b
dir_archive('memo', {}, cached=True)
>>> b.keys()   
[]
>>> b.archive.keys()
['a', 'c', 'b', 'e', 'd', 'g', 'f']
>>> b.load('a')
>>> b
dir_archive('memo', {'a': 0}, cached=True)
>>> b.load('b')
>>> b.load('f')
>>> b.load('g')
>>> b['g'](b['f'](b['a'],b['b']))
1

klepto还为sql归档提供了相同的接口。

代码语言:javascript
复制
>>> print klepto.archives.sql_archive.__new__.__doc__
initialize a dictionary with a sql database archive backend

    Connect to an existing database, or initialize a new database, at the
    selected database url. For example, to use a sqlite database 'foo.db'
    in the current directory, database='sqlite:///foo.db'. To use a mysql
    database 'foo' on localhost, database='mysql://user:pass@localhost/foo'.
    For postgresql, use database='postgresql://user:pass@localhost/foo'. 
    When connecting to sqlite, the default database is ':memory:'; otherwise,
    the default database is 'defaultdb'. If sqlalchemy is not installed,
    storable values are limited to strings, integers, floats, and other
    basic objects. If sqlalchemy is installed, additional keyword options
    can provide database configuration, such as connection pooling.
    To use a mysql or postgresql database, sqlalchemy must be installed.

    Inputs:
        name: url for the sql database [default: (see note above)]
        dict: initial dictionary to seed the archive
        cached: if True, use an in-memory cache interface to the archive
        serialized: if True, pickle table contents; otherwise cast as strings

>>> c = klepto.archives.sql_archive('database')
>>> c.update(b)
>>> c
sql_archive('sqlite:///database', {'a': 0, 'b': 1, 'g': <function <lambda> at 0x10446b1b8>, 'f': <built-in function max>}, cached=True)
>>> c.dump()

现在磁盘上的相同对象也在sql归档中。我们可以将新对象添加到这两个存档中。

代码语言:javascript
复制
>>> b['x'] = 69
>>> c['y'] = 96
>>> b.dump('x')
>>> c.dump('y')

在这里获取kleptohttps://github.com/uqfoundation

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14668475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档