2012-08-06 13 views
14

Analizando costosamente un archivo, que genera un diccionario de ~ 400 pares clave, valor, que rara vez se actualiza. Anteriormente tenía una función que analizaba el archivo, lo escribía en un archivo de texto en la sintaxis del diccionario (es decir, dict = {'Adam': 'Room 430', 'Bob': 'Room 404'}) etc., y lo copiaba y pegaba en otra función cuyo único propósito era devolver ese diccionario analizado.¿Manera elegante de almacenar el diccionario permanentemente con Python?

Por lo tanto, en cada archivo donde usaría ese diccionario, importaría esa función y la asignaría a una variable, que ahora es ese diccionario. ¿Se pregunta si hay una manera más elegante de hacerlo, que no implica copiar y pegar explícitamente el código? El uso de una base de datos parece innecesario, y el archivo de texto me dio la ventaja de ver si el análisis se realizó correctamente antes de agregarlo a la función. Pero estoy abierto a sugerencias.

+0

Duplicar posibles: http://stackoverflow.com/questions/7100125/storing-python-dictionaries –

+0

Serialice a JSON, escribir JSON a un archivo, leer un archivo, 'json.loads()' ¿después? – favoretti

+0

Vea también: [¿Cómo guardar un diccionario en un archivo en Python?] (Http://stackoverflow.com/q/19201290/562769) y [Almacenar diccionarios de Python] (http://stackoverflow.com/q/7100125/562769). –

Respuesta

33

¿Por qué no lo descarga a un archivo JSON, y luego lo carga desde allí donde lo necesita?

import json 

with open('my_dict.json', 'w') as f: 
    json.dump(my_dict, f) 

# elsewhere... 

with open('my_dict.json') as f: 
    my_dict = json.load(f) 

Cargando desde JSON es bastante eficiente.

Otra opción sería usar pickle, pero a diferencia de JSON, los archivos que genera no son legibles por humanos, por lo que pierde la verificación visual que le gustaba de su método anterior.

3

Si la eficacia del almacenamiento importa, use Pickle o CPickle (para la ganancia del rendimiento de ejecución). Como señaló Amber, también puedes volcar/cargar a través de Json. Será legible por humanos, pero requiere más disco.

4

JSON es probablemente el camino correcto en muchos casos; pero podría haber una alternativa. Parece que tus claves y tus valores siempre son cadenas, ¿verdad? Puede considerar usar dbm/anydbm. Estas son "bases de datos" pero actúan casi exactamente como los diccionarios. Son geniales para la persistencia de datos baratos.

>>> import anydbm 
>>> dict_of_strings = anydbm.open('data', 'c') 
>>> dict_of_strings['foo'] = 'bar' 
>>> dict_of_strings.close() 
>>> dict_of_strings = anydbm.open('data') 
>>> dict_of_strings['foo'] 
'bar' 
4

Si las claves son todas las cadenas, se puede utilizar el módulo de shelve

Un shelf es un diccionario-como persistente, objeto. La diferencia con las bases de datos "dbm" es que los valores (¡no las claves!) En un estante pueden ser objetos de Python esencialmente arbitrarios, cualquier cosa que el módulo pickle pueda manejar. Esto incluye la mayoría de instancias de clase, tipos de datos recursivos, y objetos que contienen muchos subobjetos compartidos. Las claves son cadenas normales.

json sería una buena opción si necesita usar los datos de otros idiomas

+0

También he leído cosas que me llevan a creer que los archivos 'shelve' no son compatibles con plataformas cruzadas porque la base de datos subyacente utilizada puede diferir de una a otra (y no hay una buena manera de controlarla). – martineau

2

le sugiero que considere el uso del módulo de shelve ya que su estructura de datos es un mapeo. Esa fue mi answer a una pregunta similar titulado If I want to build a custom database, how could I? También hay un poco de código de ejemplo en otro answer mío promover su uso para la cuestión How to get a object database?

ActiveState tiene una alta calificación PersistentDict receta que soporta CSV, JSON, y la salida de la salmuera formatos de archivo. Es bastante rápido ya que los tres de esos formatos se implementan en C (aunque la receta en sí es pura Python), por lo que el hecho de que lea todo el archivo en la memoria cuando se abra puede ser aceptable.

0

en la dirección JSON también hay algo llamado simpleJSON. La primera vez que uso json en python, la biblioteca json no funcionó para mí/no pude resolverlo. simpleJSON fue ... más fácil de usar

0

La serialización JSON (o YAML, o lo que sea) es probablemente mejor, pero si ya está escribiendo el diccionario en un archivo de texto en sintaxis Python, con un enlace de nombre de variable, podría escribir eso en un archivo .py en su lugar. Entonces ese archivo python sería importable y utilizable como es. No es necesario el enfoque de "función que devuelve un diccionario", ya que puede usarlo directamente como global en ese archivo. p.ej.

# generated.py 
please_dont_use_dict_as_a_variable_name = {'Adam': 'Room 430', 'Bob': 'Room 404'} 

en lugar de:

# manually_copied.py 
def get_dict(): 
    return {'Adam': 'Room 430', 'Bob': 'Room 404'} 

La única diferencia es que manually_copied.get_dict le da una nueva copia del diccionario cada vez, mientras que generated.please_dont_use_dict_as_a_variable_name [1] es un objeto compartido sola. Esto puede importar si está modificando el diccionario en su programa después de recuperarlo, pero siempre puede usar copy.copy o copy.deepcopy para crear una nueva copia si necesita modificar una independientemente de las demás.


[1] dict, list, str, int, map, etc son generalmente vistos como malos nombres de variables. La razón es que estos ya están definidos como incorporados, y se usan con mucha frecuencia. Entonces, si le das un nombre así a algo, al menos va a causar disonancia cognitiva a las personas que leen tu código (incluyéndote a ti después de que has estado fuera por un tiempo) ya que tienen que tener en cuenta que "dict doesn ' t significa lo que normalmente hace aquí ". También es bastante probable que en algún momento obtengas un error exasperante al informar que los objetos dict no se pueden llamar (o algo así), porque alguna parte del código está tratando de usar el tipo dict, pero está recibiendo el objeto de diccionario que enlazó con el nombre dict en su lugar.

14

¿Por qué meterse con todos estos métodos de serialización? Ya está escrito en un archivo como un dict de Python (aunque con el desafortunado nombre 'dict'). Cambie su programa para escribir los datos con un mejor nombre de variable, tal vez 'datos', o 'catálogo', y guarde el archivo como un archivo de Python, digamos data.py. Luego puede importar los datos directamente en el tiempo de ejecución sin ninguna copia/pegado torpe o JSON/shelve/etc. análisis:

from data import catalog 
+1

+1: Esta es la mejor respuesta a la pregunta del OP, en mi humilde opinión. – martineau

Cuestiones relacionadas