辞書をファイルに保存する方法は?


139

dictの値を変更し、dictをテキストファイルに保存する(形式は同じである必要があります)ことに問題がありmember_phoneます。フィールドを変更したいだけです。

私のテキストファイルは次の形式です。

memberID:member_name:member_email:member_phone

そして私はテキストファイルを次のように分割します:

mdict={}
for line in file:
    x=line.split(':')
    a=x[0]
    b=x[1]
    c=x[2]
    d=x[3]
    e=b+':'+c+':'+d

    mdict[a]=e

member_phone格納されてdいる値を変更しようとすると、キーによってフローされずに値が変更され、

def change(mdict,b,c,d,e):
    a=input('ID')
    if a in mdict:
        d= str(input('phone'))
        mdict[a]=b+':'+c+':'+d
    else:
        print('not')

そして、どのようにdictを同じフォーマットのテキストファイルに保存しますか?

回答:


258

Pythonには、この種のもののためのピクルモジュールがあります。

これらの関数は、ほぼすべてのオブジェクトを保存およびロードするために必要なすべてです。

def save_obj(obj, name ):
    with open('obj/'+ name + '.pkl', 'wb') as f:
        pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL)

def load_obj(name ):
    with open('obj/' + name + '.pkl', 'rb') as f:
        return pickle.load(f)

これらの関数はobj、現在の作業ディレクトリに、オブジェクトの保存に使用されるフォルダーがあることを前提としています。

pickle.HIGHEST_PROTOCOL常に便利なことができませんでしたバイナリフォーマットを、ですが、パフォーマンスのために良いです。プロトコル0はテキスト形式です。

Pythonのコレクションを保存するために、shelveモジュールがあります。


1
save_objファイルがobj/'+ name + '.pklすでに存在している必要があります。という名前のディクショナリを作成し、Qそこにデータを入力して、save_obj(Q, "Qtable")エラーが発生した呼び出しを行いFileNotFoundError: [Errno 2] No such file or directory: 'obj/Qtable.pkl'ました。ファイルに書き込む前に、最初にどのようにファイルを作成しますか?
つまようじアネモネ

1
@ToothpickAnemoneはwb+、ファイルの作成に使用します。例:with open('obj/'+ name + '.pkl', 'wb+')
andrey.s 2017年

1
@ andrey.s:それは問題に対処していないので、あなたが言ったことは何の変化ももたらさないと思います。
martineau

1
@Toothpick Anemone:+モードにa を追加しても問題には影響しません(andrey.sは正しくありません)。あなたの問題は、1つまたは2つの理由が原因であるように聞こえます。以下のためにsave_obj()仕事にこの答えでは、という名前のサブディレクトリが"obj"なければなりませんすでに存在しているためopen()、自動的に作成しません。次に、の最初の引数save_obj()は、保存するPythonオブジェクトであり、サブディレクトリの名前ではありません(ただしQ、例のsave_obj(Q, "Qtable")呼び出しで何を意味しているかは完全には明確ではありません)。でまだ存在しない場合は、ディレクトリを作成できますos.mkdir()
martineau

168

おそらくPickleが最良のオプションですが、NumPyを使用してディクショナリをファイルに保存およびロードする方法を誰かが疑問に思う場合のために:

import numpy as np

# Save
dictionary = {'hello':'world'}
np.save('my_file.npy', dictionary) 

# Load
read_dictionary = np.load('my_file.npy',allow_pickle='TRUE').item()
print(read_dictionary['hello']) # displays "world"

参考:NPYファイルビューア


4
.item()は何のためのものですか?
ガルザー

この回答が@Zahの「pickle」回答よりも支持されないのはなぜですか?より複雑なスペース?
ネイサン

1
ピクルはnumpyが独立したプロジェクトであるpythonの標準ライブラリの一部であるため、@ frankの可能性。
Maxim Veksler 2018

2
@Gulzarが私が調べたところから、np.loadはndarrayを返し(それをtype(read_dictionary)明らかにする)、. item()は基本的にその要素をここで
abhyudayasrinet

2
@Shaiはnumpyパッケージをインストールしましたか...?
エベン2018

26

json辞書やその他のデータをJSON形式に簡単にマッピングできる場合にも、モジュール使用できます。

import json

# Serialize data into file:
json.dump( data, open( "file_name.json", 'w' ) )

# Read data from file:
data = json.load( open( "file_name.json" ) )

このソリューションは多くの利点をもたらします。たとえばPython 2.xおよびPython 3.xで変更されていない形式で機能し、さらに、JSON形式で保存されたデータは、多くの異なるプラットフォームまたはプログラム間簡単に転送できます。このデータも人間が読める形式です。


良いアプローチですが、openによって作成されたコンテキストの代わりに直接使用するのは安全ではないと思いますwith。保証はありjson.dumpますか?失敗した場合、ファイルハンドルは閉じられますか?
Dr_Zaszuś

18

最初の質問が何であるかはわかりませんが、辞書をファイルに保存する場合は、jsonライブラリを使用する必要があります。ロードおよびプット関数のドキュメントを調べます。


なぜjson?"repr"を使用してPython辞書をファイルにダンプする方が簡単です
mguijarr

5
@mguijarrですが、パースするのは簡単ではありません。さらに、jsonは手動で簡単に編集でき、他のプログラムにインポートできます。
カルハート2013年

1
Iジョンの提案のように-良いと簡単な例については、この記事を参照してくださいstackoverflow.com/a/11027021/765827
jacanterbury

9

dictをファイルに保存してロードします。

def save_dict_to_file(dic):
    f = open('dict.txt','w')
    f.write(str(dic))
    f.close()

def load_dict_from_file():
    f = open('dict.txt','r')
    data=f.read()
    f.close()
    return eval(data)

3

あなたが扱っているような文字列の辞書の場合、それはPythonの組み込みテキスト処理機能のみを使用して行うことができます。

(値が他のものである場合、これは機能しないことに注意してください。)

with open('members.txt') as file:
    mdict={}
    for line in file:
        a, b, c, d = line.strip().split(':')
        mdict[a] = b + ':' + c + ':' + d

a = input('ID: ')
if a not in mdict:
    print('ID {} not found'.format(a))
else:
    b, c, d = mdict[a].split(':')
    d = input('phone: ')
    mdict[a] = b + ':' + c + ':' + d  # update entry
    with open('members.txt', 'w') as file:  # rewrite file
        for id, values in mdict.items():
            file.write(':'.join([id] + values.split(':')) + '\n')

これは辞書では機能しません:file.write( ':'。join([id] + values.split( ':'))+ '\ n')AttributeError: 'dict' object has no attribute 'split'
シャイ・アロン2018年

@ShaiAlon:すべてではありません、いいえ。これ、値が文字列(split()メソッドを持つ)であるもので確実に機能します。これがこの質問のトピックです。辞書の辞書で使用しようとしているようです。そのため、これらの辞書では機能しません。また、質問(および提供される回答のコンテキスト)を実際には理解していないため、人々からの反対投票には感謝しません。回答を更新して使用するのが適切な場合に備えますので、反対票を取り消してください。
martineau

3

JSONのファイルは人間が読める形式であるため、ピクル形式ではなくJSON形式を使用してデータを保存することをお勧めします。これにより、データが小さいためデバッグが容易になります。JSONファイルは、他のプログラムでもデータの読み書きに使用されます。あなたはそれについてここでもっと読むことができます

JSONモジュールをインストールする必要があります。pipを使用してインストールできます。

pip install json


# To save the dictionary into a file:
json.dump( data, open( "myfile.json", 'w' ) )

これにより、myfileという名前のjsonファイルが作成されます。

# To read data from file:
data = json.load( open( "myfile.json" ) )

これにより、myfile.jsonデータが読み取られ、データオブジェクトに格納されます。


2

本当に辞書を使いたくないのであれば、csvPythonモジュールを使用してファイルを読み取ることが最善の解決策だと思います。次に、データの行を取得し、変更しmember_phoneたり、必要に応じて何でもできます。最後に、csvモジュールを再度使用して、開いたときと同じ形式でファイルを保存できます。

読み取り用のコード:

import csv

with open("my_input_file.txt", "r") as f:
   reader = csv.reader(f, delimiter=":")
   lines = list(reader)

書くためのコード:

with open("my_output_file.txt", "w") as f:
   writer = csv.writer(f, delimiter=":")
   writer.writerows(lines)

もちろん、change()関数を適合させる必要があります。

def change(lines):
    a = input('ID')
    for line in lines:
      if line[0] == a:
        d=str(input("phone"))
        line[3]=d
        break
    else:
      print "not"

の意味Of course, you need to adapt your change() function:
kRazzy R

1
質問では、a dict が使用されていましたが、csvはリストのように機能します
mguijarr 2017

1

計時はしていませんが、h5はピクルスより高速です。圧縮後のファイルサイズはほぼ確実に小さくなります。

import deepdish as dd
dd.io.save(filename, {'dict1': dict1, 'dict2': dict2}, compression=('blosc', 9))

-2

迅速で汚い解決策:dictを文字列に変換してファイルに保存します。例:

#dict could be anything:

savedict = open('savedict001.txt', 'w')
savedict.write(str(dict))
savedict.close()

文字列のキーとしてpd.Seriesまたはnp.ndarrayがある場合は、dictをstrに変換して保存しても機能しません。
アルパンSrivastava
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.