質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

4回答

8473閲覧

Python - Pickleの使い方について

starrow1103

総合スコア137

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/04/05 01:13

編集2017/04/05 01:44

pickleモジュールを使うと、バイナリデータとしてデータを保存することができますが、
複数データの取り扱いについての情報が少ないので、求めています。

例えば

py3

1with open("test.pickle","wb") as f: 2 for i in range(10): 3 data = {i:"<<<data%d>>>" % i} 4 pickle.dump(data,f)

このtest.pickleファイルには以下の情報が格納されたわけですが。

pickle

1{0: '<<<data0>>>'} 2{1: '<<<data1>>>'} 3{2: '<<<data2>>>'} 4{3: '<<<data3>>>'} 5{4: '<<<data4>>>'} 6{5: '<<<data5>>>'} 7{6: '<<<data6>>>'} 8{7: '<<<data7>>>'} 9{8: '<<<data8>>>'} 10{9: '<<<data9>>>'}

こいつらをload()するには、

py3

1with open("test.pickle","wb") as f: 2 for i in range(10): 3 yield pickle.load(f)

とかなんとかやってやりゃあいいんですが、

たとえば、3番目のでーただけ欲しいぜ!って時は上から読み込まなきゃいけないのかな。
そこら辺の使い方がどうも転がっていない様子。

だれかご存知でしたら、ご教授ください。

追記

一応、以下のようにして1行ずつ読み込んでいるのかは知らないけれど、目的の行のでーたのみ取得は可能

def get(): with open("test.pickle","rb") as f: while True: try: yield pickle.load(f) except: break data = get() d = list(data)[3] print(d)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

pickleでは、複数回に分けてオブジェクトを対象ファイルに書き出すということは想定されていないと思います。

pickle.dump() 1回の呼び出しで出力されるデータは、pickleのフォーマットとして完結しています。このため、複数回実行した場合、ファイル上では追記されていくので「複数のpickleデータを並べた状態」になっています。そのようなフォーマットを直接的に扱う便利な機能はpickleモジュールにはなさそうです。

(これは、同等のインターフェースをもつjsonモジュールでも同じ事が言えます)

Databaseにpickleデータを保存する、という手法は時々見掛けます。
他には、pickleをDB的まとめて扱うZODBというのがあったりします。探せばそういった便利なライブラリが他にもあるかも知れません。

投稿2017/04/05 01:55

shimizukawa

総合スコア1847

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

starrow1103

2017/04/05 02:01

>そのようなフォーマットを直接的に扱う便利な機能はpickleモジュールにはなさそう 自分で作ってみるのも面白そうなんでちょっとやってみます。 ご紹介いただいたZODBも面白そうですね。とりあえずdocument読んでみますね。
guest

0

ベストアンサー

Python 標準ライブラリの shelve が目的にあうと思います。
内部では pickle が使われます。

“シェルフ (shelf, 棚)” は辞書に似た永続性を持つオブジェクトです。 “dbm” データベースとの違いは、シェルフの値 (キーではありません!) は実質上どんな Python オブジェクトにも — pickle モジュールが扱えるなら何でも — できるということです。これにはほとんどのクラスインスタンス、再帰的なデータ型、沢山の共有されたサブオブジェクトを含むオブジェクトが含まれます。キーは通常の文字列です。

Python

1import shelve 2 3# Write 4with shelve.open('test.shelve', 'c') as db: 5 for i in range(10): 6 db[str(i)] = {i:"<<<data%d>>>" % i} 7 8# Read 9with shelve.open('test.shelve', 'r') as db: 10 data9 = db['9'] 11 12print(data9) # -> {9: '<<<data9>>>'}

投稿2017/04/05 11:01

copepoda

総合スコア324

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

starrow1103

2017/04/06 02:29

これは便利そうですね!まさにpickleを使いこなした感じのライブラリ・・・。 少し触ってみますね。
guest

0

シリアライズしてシーケンシャルなファイルに保存してるわけですから、少なくとも内部的には先頭から読んでいくしかないと思います。省略的な記法はあるのかもしれませんが、知りません。
ご承知の上で書いているとは思いますが、例に上がっているコードならリスト型かひとつの辞書型にした方がいいと思います。

投稿2017/04/05 01:46

Lhankor_Mhy

総合スコア35871

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

starrow1103

2017/04/05 02:02

>少なくとも内部的には先頭から読んでいくしかない 結局はこれですよね。CSVの読み込みでも同じようなことが言えますが、 最近「メモリ的に優しい」使い方に興味を持っていて、この投稿をした次第です。 データベース使えやって話ですね
guest

0

pickle.dump するところで、複数回dumpしていますが、うまく保存されていますか?

私なら以下のように保存し、呼び出す側で取得しやすいようにします。

python

1>>> with open('test.pickle', 'wb') as f: 2... data = [] 3... for i in range(10): 4... data.append({i:"<<<data%d>>>" % i}) 5... pickle.dump(data,f) 6... 7>>> with open('test.pickle', 'rb') as f: 8... obj = pickle.load(f) 9... 10>>> print(obj) 11[{0: '<<<data0>>>'}, {1: '<<<data1>>>'}, {2: '<<<data2>>>'}, {3: '<<<data3>>>'}, {4: '<<<data4>>>'}, {5: '<<<data5>>>'}, {6: '<<<data6>>>'}, {7: '<<<data7>>>'}, {8: '<<<data8>>>'}, {9: '<<<data9>>>'}] 12>>> obj[2] 13{2: '<<<data2>>>'}

投稿2017/04/05 01:39

terapyon

総合スコア313

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

starrow1103

2017/04/05 01:42

>複数回dumpしていますが、うまく保存されていますか? dumpを繰り返すと、追記できることを発見したのですが、なかなかその情報がありません。 回答にいただいた方法は直列化(というのでしょうか)でしょうか。 確かに、そのやりかたで楽なのですが、、、 例えば、いくつかの膨大なデータ(といっても数メガ程度だと思うのですが)をpickleでちょいちょいしたいなと思った時に、全部読み込むのはメモリ的にやさしくないとおもいまして。 1行ずつ読み込めるのであればそればベストだと思っていたのです。
terapyon

2017/04/05 02:15

shimizukawaさんが指摘している通り、取り出すいい方法が無いようですね。 ZODBのpersistentオブジェクトであれば可能だと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問