2012-08-06 23 views
14

現在、高価に更新される〜400個のキー、値のペアの辞書を生成する、ファイルを高価に解析しています。以前はファイルを解析し、辞書構文(例えばdict = {'Adam': 'Room 430', 'Bob': 'Room 404'})などのテキストファイルに書き込んで、その解析された辞書を返すことを目的とする別の関数にコピーして貼り付けました。Pythonで永遠に辞書を保存するためのエレガントな方法は?

したがって、その辞書を使用するすべてのファイルで、その関数をインポートし、その辞書を変数に割り当てます。明示的にコードをコピーして貼り付けることを伴わない、よりエレガントなやり方があるのだろうか?データベースの種類を使用することは不要と思われ、テキストファイルを使用すると、関数に関数を追加する前に解析が正しく行われたかどうかを確認できます。しかし、私は提案に開放されています。

+0

可能性の重複:http://stackoverflow.com/questions/7100125/storing-python-dictionaries –

+0

、JSONにシリアライズファイルにJSONを書き込み、ファイルを読み込む、 'json.loads()'その後? – favoretti

+0

参照:[Pythonでファイルに辞書を保存する方法](http://stackoverflow.com/q/19201290/562769)と[Python辞書を格納する](http://stackoverflow.com/q/7100125)/562769)。 –

答えて

33

なぜそれをJSONファイルにダンプしてから、そこからロードしてください。

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) 

JSONからの読み込みはかなり効率的です。

もう1つのオプションはpickleですが、JSONとは異なり、生成するファイルは人間が読める形式ではありません。したがって、以前の方法のように視覚的な確認ができなくなります。

3

ストレージ効率が重要な場合は、PickleまたはCPickle(実行パフォーマンスの向上のため)を使用します。 Amberが指摘するように、Jsonを介してダンプ/ロードすることもできます。それは人間が読めるが、より多くのディスクを必要とする。

4

多くの場合、JSONはおそらく正しい方法です。しかし、代替手段があるかもしれない。あなたのキーのように見え、あなたの値は常に文字列です、そうですか? dbm/anydbmを使用することをおすすめします。これらは「データベース」ですが、辞書とほぼ同じように動作します。安価なデータ永続性を実現します。

>>> 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

キーは、すべての文字列である場合、あなたはshelfは、永続的な、辞書のようなオブジェクトである

shelveモジュールを使用することができます。 "dbm"データベースとの違いは、シェルフ内の値(キーではありません)は と基本的に任意のPythonオブジェクト(ピクルモジュール が処理できるもの)です。これには、ほとんどのクラスインスタンス、再帰的データ型、 、および多くの共有サブオブジェクトを含むオブジェクトが含まれます。キーは普通の文字列 です。

jsonは、あなたが他の言語

+0

私は 'shelve'ファイルがクロスプラットフォーム対応ではないと思うようなものも読んでいます。使用する基礎となるデータベースが違うかもしれないからです(そして、それを制御する良い方法はありません)。 – martineau

2

からのデータを使用する必要がある場合、私はあなたのデータ構造がマッピングされるので、あなたがshelveモジュールを使用することを検討してお勧め選ぶとよいでしょう。 If I want to build a custom database, how could I?質問How to get a object database?

のActiveStateが高い評価をPersistentDict csvファイルをサポートしていますレシピ、JSON、およびピクルス出力を持っているため、その使用を推進する鉱山の別のanswerのサンプルコードのビットもあります題し同様の質問に対する私のanswerた ファイル形式。これら3つのフォーマットはすべてC言語で実装されているので(レシピ自体は純粋なPythonですが)、かなり高速です。ファイルを開いたときにファイル全体をメモリに読み込むということは受け入れられるかもしれません。

0

JSON方向にはsimpleJSONというものもあります。私の初めてのPythonのjsonライブラリを使用して私のための仕事をdidnt /私はそれを把握できませんでした。 simpleJSONは使いやすい...

0

JSON(またはYAMLなど)のシリアル化はおそらくより優れていますが、すでにPython構文でテキストファイルに辞書を書き込んでいる場合は、その代わりに.pyファイルに書き込むことができます。そのPythonファイルをそのままインポートして使用することができます。あなたは直接そのファイル内のグローバルとして使うことができるので、 "辞書を返す関数"のアプローチは必要ありません。例えば

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

いうより:

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

唯一の違いは、generated.please_dont_use_dict_as_a_variable_name [1]単一の共有オブジェクトであるのに対しmanually_copied.get_dictは、あなたに毎回辞書の新しいコピーを与えることです。これは検索後にプログラム内の辞書を変更する場合には重要ですが、他と独立して変更する必要がある場合は常にcopy.copyまたはcopy.deepcopyを使用して新しいコピーを作成してください。等


[1] dictliststrintmap、一般的に悪い変数名とみなされます。その理由は、これらが既にビルトインとして定義されており、非常に一般的に使用されているためです。だから、もしあなたがそのような名前をつけても、少なくとも「dict doesn」ということを心に留めておかなければならないので、コードを読んでいる人々のために認知不調を引き起こします。それは通常ここで何をしているのかを意味します。また、ある種のコードがタイプdictを使用しようとしているので、dictのオブジェクトが呼び出し可能でない(または何か)ことが報告されている紛らわしい解決のバグをいつの間にか取得する可能性があります代わりに名前dictにバインドした辞書オブジェクト。

14

なぜこれらすべてのシリアライズ方法が混乱しますか?これは既にPythonのdictとしてファイルに書き出されています(ただし、残念なことに 'dict'という名前が付いています)。プログラムを変更して、より良い変数名(おそらく 'data'または 'catalog')でデータを書き出し、ファイルをPythonファイルとして保存します。たとえば、data.pyとします。次に、不器用なコピー/貼り付けやJSON/shelve/etcなどなく、実行時に直接データをインポートできます。パース:

from data import catalog 
+1

+1:これは、OPの質問IMHOに対する最善の答えです。 – martineau