ejemplos - Pickle contra shelve almacenando grandes diccionarios en Python
pickle python (2)
Si estoy almacenando un directorio grande como un archivo pickle
, ¿cargarlo a través de cPickle
significa que todo se consumirá en la memoria de una vez?
Si es así, ¿existe una forma multiplataforma para obtener algo como pickle
, pero acceda a cada entrada con una tecla en un elemento (es decir, evite cargar todo el diccionario en la memoria y solo cargue cada entrada por nombre)? Sé que shelve
se supone que debe hacer esto: ¿es eso tan portátil como un pickle
?
Sé que Shelve se supone que debe hacer esto: ¿es eso tan portátil como un pepinillo?
Sí. shelve
es parte de la biblioteca estándar de Python y está escrito en Python.
Editar
Así que si tienes un diccionario grande:
bigd = {''a'': 1, ''b'':2, # . . .
}
Y desea guardarlo sin tener que leerlo todo más tarde, luego no lo guarde como un pepinillo, sería mejor guardarlo como un estante, una especie de diccionario de disco.
import shelve
myShelve = shelve.open(''my.shelve'')
myShelve.update(bigd)
myShelve.close()
Luego más tarde podrás:
import shelve
myShelve = shelve.open(''my.shelve'')
value = myShelve[''a'']
value += 1
myShelve[''a''] = value
Básicamente, trata el objeto de la estantería como un dict, pero los elementos se almacenan en el disco (como encurtidos individuales) y se leen según sea necesario.
Si sus objetos podrían almacenarse como una lista de propiedades, entonces sqlite puede ser una buena alternativa. Los estantes y los encurtidos son convenientes, pero Python solo puede acceder a ellos, pero la base de datos sqlite puede leerse en la mayoría de los idiomas.
Si desea un módulo que sea más robusto que el shelve
, puede mirar klepto
. klepto
está diseñado para proporcionar una interfaz de diccionario para el almacenamiento klepto
de la plataforma en el disco o la base de datos, y está diseñado para trabajar con datos grandes.
Aquí, primero creamos algunos objetos decapados almacenados en el disco. Utilizan el dir_archive
, que almacena un objeto por archivo.
>>> 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
Ahora, todos los datos están en el disco, vamos a seleccionar y elegir los que queremos cargar en la memoria. b
es el dict en memoria, mientras que b.archive
mapea la colección de archivos en una vista de diccionario.
>>> 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
también proporciona la misma interfaz para un archivo sql
.
>>> 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()
Donde ahora los mismos objetos en el disco también están en un archivo sql. Podemos agregar nuevos objetos a cualquier archivo.
>>> b[''x''] = 69
>>> c[''y''] = 96
>>> b.dump(''x'')
>>> c.dump(''y'')
Obtenga klepto
aquí: https://github.com/uqfoundation