Python辞書の保存


198

私は.csvファイルを使用してデータをPythonに出し入れすることに慣れていますが、これには明らかな課題があります。辞書(または辞書のセット)をjsonまたはpckファイルに格納する簡単な方法についてアドバイスはありますか?例えば:

data = {}
data ['key1'] = "keyinfo"
data ['key2'] = "keyinfo2"

これを保存する方法と、ロードする方法の両方を知りたいです。


8
jsonまたはpickle標準モジュールのドキュメントを読みましたか?
グレッグヒューギル2011

回答:


443

ピクル保存:

try:
    import cPickle as pickle
except ImportError:  # python 3.x
    import pickle

with open('data.p', 'wb') as fp:
    pickle.dump(data, fp, protocol=pickle.HIGHEST_PROTOCOL)

引数に関する追加情報については、pickleモジュールのドキュメントを参照してくださいprotocol

ピクルロード

with open('data.p', 'rb') as fp:
    data = pickle.load(fp)

JSON保存:

import json

with open('data.json', 'w') as fp:
    json.dump(data, fp)

sort_keysまたはなどの追加の引数を指定indentして、きれいな結果を得ることができます。引数sort_keysはキーをアルファベット順にソートし、インデントindent=Nスペースでデータ構造をインデントします。

json.dump(data, fp, sort_keys=True, indent=4)

JSONロード:

with open('data.json', 'r') as fp:
    data = json.load(fp)

4
JSONはディクショナリをネイティブに実行します(ただし、メモリ内にある間は、Pythonディクショナリのように正確に動作しないことは明らかですが、永続化のために同じです)。実際、jsonの基本単位は「オブジェクト」であり、{<string>:<value>}として定義されています。見覚えがあります?標準ライブラリのjsonモジュールは、すべてのPythonネイティブタイプをサポートし、jsonの最小限の知識で簡単に拡張して、ユーザー定義クラスをサポートできます。JSONホームページは、3ページを超える印刷ページで言語を完全に定義しているため、すばやく吸収/消化するのは簡単です。
ジョナサン

1
の3番目の引数についても知っておく価値がpickle.dumpあります。ファイルが人間が読めるようにする必要がない場合は、処理速度が大幅に向上します。
Steve Jessop、2011

11
あなたが追加した場合sort_keysインデントダンプコールに引数を、あなたは非常にきれい結果を取得します。例:json.dump(data, fp, sort_keys=True, indent=4)。詳細は こちら
juliusmh 2016年

1
おそらく使用する必要がありますpickle.dump(data, fp, protocol=pickle.HIGHEST_PROTOCOL)
Martin Thoma

1
python 3については、使用import pickle
danger89

35

最小限の例、ファイルに直接書き込む:

import json
json.dump(data, open(filename, 'wb'))
data = json.load(open(filename))

または安全に開閉する:

import json
with open(filename, 'wb') as outfile:
    json.dump(data, outfile)
with open(filename) as infile:
    data = json.load(infile)

ファイルではなく文字列で保存したい場合:

import json
json_str = json.dumps(data)
data = json.loads(json_str)


5

ファイルに書き込むには:

import json
myfile.write(json.dumps(mydict))

ファイルから読み取るには:

import json
mydict = json.loads(myfile.read())

myfile dictを保存したファイルのファイルオブジェクトです。


あなたはjsonがファイルを引数として取り、それらに直接書き込むことを知っていますか?

json.dump(myfile)およびjson.load(myfile)
Niklas R

5

シリアル化した後で他のプログラムのデータが必要ない場合は、shelveモジュールを強くお勧めします。永続的な辞書と考えてください。

myData = shelve.open('/path/to/file')

# check for values.
keyVar in myData

# set values
myData[anotherKey] = someValue

# save the data for future use.
myData.close()

2
辞書全体を保存したい、または辞書全体をロードしたい場合jsonは、より便利です。shelve一度に1つのキーにアクセスする場合にのみ優れています。
agf 2011

3

pickleまたはの代替が必要な場合はjson、を使用できますklepto

>>> init = {'y': 2, 'x': 1, 'z': 3}
>>> import klepto
>>> cache = klepto.archives.file_archive('memo', init, serialized=False)
>>> cache        
{'y': 2, 'x': 1, 'z': 3}
>>>
>>> # dump dictionary to the file 'memo.py'
>>> cache.dump() 
>>> 
>>> # import from 'memo.py'
>>> from memo import memo
>>> print memo
{'y': 2, 'x': 1, 'z': 3}

ではklepto、を使用したserialized=True場合、辞書はmemo.pklクリアテキストではなく、漬け辞書として書き込まれます。

kleptoここから入手できます:https : //github.com/uqfoundation/klepto

dillPythonのほとんどすべてをシリアル化できるpickleので、おそらくそれ自体をピクルスにするためのより良い選択ですdillkleptoも使用できますdill

dillここから入手できます:https : //github.com/uqfoundation/dill

最初の数行の追加のmumbo-jumboは、klepto辞書をファイル、ディレクトリコンテキスト、またはSQLデータベースに格納するように構成できるためです。APIは、バックエンドアーカイブとして選択したものはすべて同じです。それはあなたがあなたがそれを使ってloadそしてdumpアーカイブと相互作用することができる「アーカイブ可能な」辞書を与える。


3

これは古いトピックですが、完全を期すために、それぞれPython 2および3の標準ライブラリの一部であるConfigParserおよびconfigparserを含める必要があります。このモジュールはconfig / iniファイルの読み取りと書き込みを行い、(少なくともPython 3では)辞書のように多くの方法で動作します。複数の辞書をconfig / iniファイルの個別のセクションに保存して呼び出すことができるという利点もあります。甘い!

Python 2.7.xの例。

import ConfigParser

config = ConfigParser.ConfigParser()

dict1 = {'key1':'keyinfo', 'key2':'keyinfo2'}
dict2 = {'k1':'hot', 'k2':'cross', 'k3':'buns'}
dict3 = {'x':1, 'y':2, 'z':3}

# make each dictionary a separate section in config
config.add_section('dict1')
for key in dict1.keys():
    config.set('dict1', key, dict1[key])

config.add_section('dict2')
for key in dict2.keys():
    config.set('dict2', key, dict2[key])

config.add_section('dict3')
for key in dict3.keys():
    config.set('dict3', key, dict3[key])

# save config to file
f = open('config.ini', 'w')
config.write(f)
f.close()

# read config from file
config2 = ConfigParser.ConfigParser()
config2.read('config.ini')

dictA = {}
for item in config2.items('dict1'):
    dictA[item[0]] = item[1]

dictB = {}
for item in config2.items('dict2'):
    dictB[item[0]] = item[1]

dictC = {}
for item in config2.items('dict3'):
    dictC[item[0]] = item[1]

print(dictA)
print(dictB)
print(dictC)

Python 3.Xの例。

import configparser

config = configparser.ConfigParser()

dict1 = {'key1':'keyinfo', 'key2':'keyinfo2'}
dict2 = {'k1':'hot', 'k2':'cross', 'k3':'buns'}
dict3 = {'x':1, 'y':2, 'z':3}

# make each dictionary a separate section in config
config['dict1'] = dict1
config['dict2'] = dict2
config['dict3'] = dict3

# save config to file
f = open('config.ini', 'w')
config.write(f)
f.close()

# read config from file
config2 = configparser.ConfigParser()
config2.read('config.ini')

# ConfigParser objects are a lot like dictionaries, but if you really
# want a dictionary you can ask it to convert a section to a dictionary
dictA = dict(config2['dict1'] )
dictB = dict(config2['dict2'] )
dictC = dict(config2['dict3'])

print(dictA)
print(dictB)
print(dictC)

コンソール出力

{'key2': 'keyinfo2', 'key1': 'keyinfo'}
{'k1': 'hot', 'k2': 'cross', 'k3': 'buns'}
{'z': '3', 'y': '2', 'x': '1'}

config.iniの内容

[dict1]
key2 = keyinfo2
key1 = keyinfo

[dict2]
k1 = hot
k2 = cross
k3 = buns

[dict3]
z = 3
y = 2
x = 1

1

jsonファイルに保存する場合、これを行う最も簡単な方法は次のとおりです。

import json
with open("file.json", "wb") as f:
    f.write(json.dumps(dict).encode("utf-8"))

なぜこれがjson.dump( )他の回答で概説されているよりも簡単なのですか?
baxx

0

私のユースケースは、複数のjsonオブジェクトをファイルに保存することでしたが、マーティの答えが私を助けてくれました。しかし、私のユースケースに対応するには、新しいエントリが保存されるたびに古いデータを上書きするため、答えは完全ではありませんでした。

複数のエントリをファイルに保存するには、古い内容を確認する必要があります(つまり、書き込み前に読み取ります)。jsonデータを保持する一般的なファイルにlistobject、ルートとしてまたはのいずれかがあります。だから私は私のjsonファイルが常にあり、list of objectsそれにデータを追加するたびに、最初にリストをロードし、そこに新しいデータを追加し、書き込み可能なファイルのインスタンスにダンプします(w):

def saveJson(url,sc): #this function writes the 2 values to file
    newdata = {'url':url,'sc':sc}
    json_path = "db/file.json"

    old_list= []
    with open(json_path) as myfile:  #read the contents first
        old_list = json.load(myfile)
    old_list.append(newdata)

    with open(json_path,"w") as myfile:  #overwrite the whole content
        json.dump(old_list,myfile,sort_keys=True,indent=4)

    return "sucess"

新しいjsonファイルは次のようになります。

[
    {
        "sc": "a11",
        "url": "www.google.com"
    },
    {
        "sc": "a12",
        "url": "www.google.com"
    },
    {
        "sc": "a13",
        "url": "www.google.com"
    }
]

注:このアプローチを機能させるにfile.json[]、初期データとしてという名前のファイルが必要です

PS:元の質問とは関係ありませんが、このアプローチは、最初にエントリがすでに存在するかどうかを確認して(1 /複数のキーに基づいて)、さらにデータを追加して保存することでさらに改善できます。誰かがそのチェックを必要とする場合、私に知らせてください、私は答えに追加します

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.