ピクルスを使用して辞書を保存するにはどうすればよいですか?


370

Pythonのドキュメントが提供する情報を確認しましたが、まだ少し混乱しています。誰かが新しいファイルを書き込むサンプルコードを投稿してから、pickleを使用して辞書をそこにダンプできますか?


5
これを読んでください:doughellmann.com/PyMOTW/pickleそして、特定の質問が必要なときに戻ってきます
pyfunc

2
-1以前のコメントを参照してください。それを試してみてください。次に、それがうまくいかなかった場合(常にそうとは限らない)、指示された質問を(テストできる仮説と2つに沿って)作成し、「他の人に質問する前に、「質問する」ことができます)。たとえば、構文エラーはありましたか?例外?値は文字化けして戻ってきましたか?

1
私はこれを使ってpygameからの情報を保存しようとしています。私は上記の情報を使用していたし、私のコードは次のようになります
Chachmu

name = raw_input( 'input file name:')tf = open(name + '。pkl'、 'wb')pickle.dump(total、tf)tf.close()
Chachmu

2
表面のオブジェクトをピクルスにする方法について、新しい質問をする必要があります
John La Rooy

回答:


727

これを試して:

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle, protocol=pickle.HIGHEST_PROTOCOL)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

print a == b

4
@houbysoft:なぜ削除したのpickle.HIGHEST_PROTOCOLですか?
Blender 2016

37
@Blender:このレベルの質問には無関係で不必要に複雑です-デフォルトのユーザーは平均的なユーザーで十分です。
houbysoft 2016

28
@houbysoft:Python 3ユーザーの場合はtrueですが、Python 2では、デフォルトのプロトコル(0)を使用すると、時間と空間が非常に非効率になるだけでなく、プロトコル2+がうまく処理する多くのことを実際に処理できません(例:新規)を使用するスタイルスタイルのクラス__slots__)。常にを使用する必要があるとは言ってHIGHEST_PROTOCOLいませんが、プロトコル0または1を使用しないようにすることは、実際にはかなり重要です。
ShadowRanger 2017

11
pickle.HIGHEST_PROTOCOL実際には何をしますか?
BallpointBen

7
@BallpointBen:Pythonのバージョンがサポートする最も高いプロトコルバージョンが選択されます:docs.python.org/3/library/pickle.html#data-stream-format
Blender

92
import pickle

your_data = {'foo': 'bar'}

# Store data (serialize)
with open('filename.pickle', 'wb') as handle:
    pickle.dump(your_data, handle, protocol=pickle.HIGHEST_PROTOCOL)

# Load data (deserialize)
with open('filename.pickle', 'rb') as handle:
    unserialized_data = pickle.load(handle)

print(your_data == unserialized_data)

の利点HIGHEST_PROTOCOLは、ファイルが小さくなることです。これにより、unpickleが大幅に高速化されることがあります。

重要なお知らせ:pickleの最大ファイルサイズは約2GBです。

別の方法

import mpu
your_data = {'foo': 'bar'}
mpu.io.write('filename.pickle', data)
unserialized_data = mpu.io.read('filename.pickle')

代替フォーマット

アプリケーションでは、次のことが重要になる場合があります。

  • 他のプログラミング言語によるサポート
  • 読み取り/書き込みパフォーマンス
  • コンパクト(ファイルサイズ)

参照:データのシリアル化形式の比較

構成ファイルを作成する方法を探している場合は、短い記事「Pythonでの構成ファイル」を読んでください。


1
2GBの制限はprotocol = 4以上で削除されたと思います。
ComputerScientist

28
# Save a dictionary into a pickle file.
import pickle

favorite_color = {"lion": "yellow", "kitty": "red"}  # create a dictionary
pickle.dump(favorite_color, open("save.p", "wb"))  # save it into a file named save.p

# -------------------------------------------------------------
# Load the dictionary back from the pickle file.
import pickle

favorite_color = pickle.load(open("save.p", "rb"))
# favorite_color is now {"lion": "yellow", "kitty": "red"}

1
open()の後にclose()を使用する必要がありますか?
PlsWork 2018

1
はい、一般的に。ただし、CPython(おそらくデフォルトのpython)では、ファイルオブジェクトが期限切れになると(何も参照しない場合)、ファイルは自動的に閉じられます。この場合、open()によって返された後は何もファイルオブジェクトを参照しないため、ロードが戻るとすぐに閉じられます。これは適切な方法とは見なされず、他のシステムで問題が発生します
Ankur S

14

一般的に、dict文字列や整数などの単純なオブジェクトだけが含まれていない限り、aのピクルは失敗します。

Python 2.7.9 (default, Dec 11 2014, 01:21:43) 
[GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from numpy import *
>>> type(globals())     
<type 'dict'>
>>> import pickle
>>> pik = pickle.dumps(globals())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save
    rv = reduce(self.proto)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle module objects
>>> 

本当にシンプルなものでも、dictしばしば失敗します。内容次第です。

>>> d = {'x': lambda x:x}
>>> pik = pickle.dumps(d)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps
    Pickler(file, protocol).dump(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump
    self.save(obj)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 649, in save_dict
    self._batch_setitems(obj.iteritems())
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 663, in _batch_setitems
    save(v)
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save
    f(self, obj) # Call unbound method with explicit self
  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 748, in save_global
    (obj, module, name))
pickle.PicklingError: Can't pickle <function <lambda> at 0x102178668>: it's not found as __main__.<lambda>

ただし、dillまたはのようなより優れたシリアライザを使用するcloudpickleと、ほとんどの辞書をピクルすることができます。

>>> import dill
>>> pik = dill.dumps(d)

またはdict、ファイルに保存したい場合...

>>> with open('save.pik', 'w') as f:
...   dill.dump(globals(), f)
... 

後者の例は、ここに掲載されている他の良い答えと同じです(これは、内容のピックル性を無視していることを除けばdict良いです)。


9
>>> import pickle
>>> with open("/tmp/picklefile", "wb") as f:
...     pickle.dump({}, f)
... 

通常はcPickle実装を使用することをお勧めします

>>> import cPickle as pickle
>>> help(pickle.dump)
Help on built-in function dump in module cPickle:

dump(...)
    dump(obj, file, protocol=0) -- Write an object in pickle format to the given file.

    See the Pickler docstring for the meaning of optional argument proto.

6

辞書を単一のファイルに保存したいだけなら、pickleそのように使用します

import pickle

a = {'hello': 'world'}

with open('filename.pickle', 'wb') as handle:
    pickle.dump(a, handle)

with open('filename.pickle', 'rb') as handle:
    b = pickle.load(handle)

複数のディクショナリを複数のファイルに保存して復元し、より複雑なデータをキャッシュおよび保存するには、anycacheを使用します。それはあなたが周りに必要な他のすべてのものを行いますpickle

from anycache import anycache

@anycache(cachedir='path/to/files')
def myfunc(hello):
    return {'hello', hello}

Anycacheは、myfunc異なるファイルへの引数に応じて異なる結果を格納しますcachedirそれらを再ロードします。

詳細については、ドキュメントを参照してください。



3
import pickle

dictobj = {'Jack' : 123, 'John' : 456}

filename = "/foldername/filestore"

fileobj = open(filename, 'wb')

pickle.dump(dictobj, fileobj)

fileobj.close()

-8

私は酸洗いが混乱していることを発見しました(おそらく私は太いためです)。しかし、これはうまくいくことがわかりました:

myDictionaryString=str(myDictionary)

これをテキストファイルに書き込むことができます。.datファイルに整数を書き込むように指示するエラーが発生したため、ピクルスの使用を中止しました。漬物を使わなかったことをお詫びします。


1
-1:再度実行するのを何時間も待たずに後で読むことができるように、それをそのまま保存する必要があります(つまり、Pythonオブジェクト)。Pickleを使用すると、Pythonオブジェクトを保存して後で読み取ることができます。
Catbuiltは2018年

これは、低品質の投稿キューに戻ってきた古い回答です。非常に単純な辞書で機能する可能性が高いという点で、悪い解決策ではありませんが、dictオブジェクトにさらに深さを含めることは非常に合理的です。名前)および/または完全な文字列表現のないオブジェクト。
ti7

1
@ ti7のポイントに追加すると、回答の技術的メリットに関係なく、この投稿はVLQではありません。この回答が不正確であると誰かが感じた場合、VLQとしてフラグを立てるのではなく、理由を説明する反対投票またはコメントを行う必要があります。
EJoshuaS-
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.