Pythonの辞書型の要素を持つリストを、エクセルで作っている資料で使いたい時がありました。普段はVS codeでJupyter Notebookを使っているのですが、その画面イメージのままエクセルで読み込むのはどうしたらいいか、スクリーンショットではなく、データとして上手く読み込ませたいと思い、やり方を調べたところ、json.dump()
でindent='\t'
を指定すると比較的きれいに読み込めるということが分かりました。以下、詳細です。
バージョン情報
以下のバージョンで確認しています。
- Python 3.12.4
- json 2.0.9
- Visual Studio code バージョン: 1.96.4
pprint関数での表示
例えば次のような辞書型のリストがあったとします。
sample = [{'store':'A','items':[{'name':'tomato','price':100},{'name':'apple','price':120}]},
{'store':'B','items':[{'name':'cabbage','price':90},{'name':'lettuce','price':150}]}]
通常のprint関数ではリストや辞書の要素が改行されることなく1行で出力されてしまいます(下の画像はVS codeでjupyter notebookを使って実行した様子)。
Pythonのpprintの使い方(リストや辞書を整形して出力)にも書かれているように、pprintモジュールのpprint関数を使うと、見やすく整形してくれます。
from pprint import pprint
pprint(sample)
この場合は多少、width
の設定を変えた方がいいかもしれませんが...
ファイルへの書き出しとエクセルでの読み込み
これをcsvファイル(テキストファイル)として書き出して、エクセルで利用したいとします。【python】print/pprintした結果をファイルに書き出す によると、stream引数を指定して書き出せばよい、とのこと。
from pprint import pprint
with open('sample.csv', 'w') as f:
pprint(sample, stream=f)
出力されたファイルをVSCodeで開くと、先程のjupyter notebookの出力セルと同じ形式で書き出されていることが確認できます。
これをエクセル(今回はLibreOffice Calc)で開くと、読み込み設定のウィンドウが出ます。
csvファイルなので"区切りのオプション"で"コンマ"を指定して読み込むのですが、...
これでは一つのセルに複数の情報が入っていて扱いづらいですね...。区切りの設定に、「スペース」とか入れてもどうもきれいに読み込めません。例えば「コンマ」と「スペース」を指定すると以下のようになりました。
これもキーと値が別のセルになっていたり、列がバラバラ、ちょっと使いにくいと思います。
json.dump()
でindentにタブを設定
そこで、何かいい方法がないか調べてみると、json.dump()
でindentにタブを設定できる、という記事(Dumping a JSON using tab indents (not spaces))を見つけました。早速試してみると...
import json
with open('sample.json', 'w') as f:
json.dump(sample, f, indent=('\t'))
書き出されたファイルを、タブを^で表現できるエディタを使って読むと確かに区切りがタブになってます。
で、これをエクセル(今回はLibreOffice Calc)で、タブで区切る様にしてして読み込むと、キーと値が同じセルにあり、さっきよりは利用しやすくなったと思います!
ちなみに、pprint関数でもindent
が指定できるので同じようにできるかと思って、 indent=('\t')
とやったら怒られましたorz。
with open('sample.txt', 'w') as f:
pprint(sample, indent='\t', stream=f)
# ValueError: invalid literal for int() with base 10: '\t'