このページでは変数の文字列表現をきれいに標準出力に出力するpprintモジュールについて解説します。
Contents
pprintモジュール
データの内容を確認する際、長いリストやネストの深い辞書をprintやファイル出力すると見づらいという経験をされた方が多いのではないでしょうか?標準ライブラリのpprintモジュールのpprint関数を使用すると、そういった変数の内容をきれいに整形して出力(pretty-print)してくれます。
https://docs.python.org/ja/3/library/pprint.html
以下のサンプルでは辞書の内容をprintではなくpprintで確認しています。改行とインデントがつけられていることが確認できます。
d = {"items": [{"code": 100, "name": "itemA", "coupons": [1, 2, 3]}, {"code": 110, "name": "itemB", "coupons": [1]},
{"code": 120, "name": "itemC", "coupons": []}, {"code": 130, "name": "itemD", "coupons": [1, 5, 8]},
{"code": 140, "name": "itemE", "coupons": [2]}], "shops": ["001", "005", "002"]}
pprint(d)
# 整形されて出力される
# {'items': [{'code': 100, 'coupons': [1, 2, 3], 'name': 'itemA'},
# {'code': 110, 'coupons': [1], 'name': 'itemB'},
# {'code': 120, 'coupons': [], 'name': 'itemC'},
# {'code': 130, 'coupons': [1, 5, 8], 'name': 'itemD'},
# {'code': 140, 'coupons': [2], 'name': 'itemE'}],
# 'shops': ['001', '005', '002']}
print関数とは異なりモジュールのインポートが必要です。(インポートしないとname 'pprint' is not definedが発生します。)また、初学者の方が混乱しやすい点でもあるのですが、前述の通りpprintというモジュールの中にpprintという関数があります。このため、以下のようなインポートではPprint module' object is not callableが発生するので注意してください。
import pprint
d = {}
pprint.pprint(d) # この書き方はOK
pprint(d) # Pprint module' object is not callableが発生
pprint関数の引数
パラメータを指定することで出力の幅など出力をカスタマイズすることができます。以下は、pprintで使用できるパラメータ例です。
| パラメータ | 意味 | デフォルト値 |
|---|---|---|
| indent | インデント幅 | 1 |
| width | 1行の文字数 | 80 |
| depth | 出力する深さ数 | None |
| compact | 幅を超過した改行が発生した際、指定幅いっぱいまで改行を抑える | False |
| sort_dicts | 自動ソートのON/OFFを設定 | False |
例で見てみましょう。
indent
indentを指定するとインデント幅を変えることができます。
pprint(d, indent=10)
# { 'items': [ { 'code': 100,
# 'coupons': [1, 2, 3],
# 'name': 'itemA'},
# {'code': 110, 'coupons': [1], 'name': 'itemB'},
# {'code': 120, 'coupons': [], 'name': 'itemC'},
# { 'code': 130,
# 'coupons': [1, 5, 8],
# 'name': 'itemD'},
# {'code': 140, 'coupons': [2], 'name': 'itemE'}],
# 'shops': ['001', '005', '002']}
widthとcompact
widthで1行の最大文字数を指定することができます。
from pprint import pprint
d = {"items": [{"code": 100, "name": "itemA"}, {"code": 110, "name": "itemB"}, {"code": 120, "name": "itemC"},
{"code": 130, "name": "itemD"}, {"code": 140, "name": "itemE"}], "shops": ["001", "005", "002"]}
pprint(d, width=30)
# {'items': [{'code': 100,
# 'coupons': [1,
# 2,
# 3],
# 'name': 'itemA'},
# {'code': 110,
# 'coupons': [1],
# 'name': 'itemB'},
# {'code': 120,
# 'coupons': [],
# 'name': 'itemC'},
# {'code': 130,
# 'coupons': [1,
# 5,
# 8],
# 'name': 'itemD'},
# {'code': 140,
# 'coupons': [2],
# 'name': 'itemE'}],
# 'shops': ['001',
# '005',
# '002']}
#
出力結果で注意していただきたいのが、widthを超えた場合は次の行から項目ごとに改行されるという点です。compactを指定すると幅いっぱいで改行するようになります。
pprint(d, width=30, compact=True)
# {'items': [{'code': 100,
# 'coupons': [1, 2,
# 3],
# 'name': 'itemA'},
# {'code': 110,
# 'coupons': [1],
# 'name': 'itemB'},
# {'code': 120,
# 'coupons': [],
# 'name': 'itemC'},
# {'code': 130,
# 'coupons': [1, 5,
# 8],
# 'name': 'itemD'},
# {'code': 140,
# 'coupons': [2],
# 'name': 'itemE'}],
# 'shops': ['001', '005',
# '002']}
depth
depthを指定すると、表示する深さを制限することができます。巨大な辞書の内容を確認する際は必ず指定したほうがよいでしょう。
pprint(d, depth=1)
# {'items': [...], 'shops': [...]}
sort_dicts 自動ソートと抑制
便利なpprintですが、pprintを使用した際戸惑うのがデフォルの挙動として辞書の内容がキーでソートされてしまう、という点です。Python3.6以降、辞書は設定した際の順序が保たれますが、pprintの出力は前述の通り、キーの昇順でソートされてしまいます。
d = {"keyX": 100, "keyA": 200, "keyB": 300}
pprint(d) # {'keyA': 200, 'keyB': 300, 'keyX': 100}
これを余計なおせっかいと感じる場合があるのですが、Python3.8以降、引数にsort_dictsというパラメータが追加されました。デフォルトではONになりキーの昇順でソートされてしまいますが、Falseを指定することでこのソートをOFFに、つまり設定した際の順序が保たれます。
d = {"keyX": 100, "keyA": 200, "keyB": 300}
pprint(d, sort_dicts=False) # {'keyX': 100, 'keyA': 200, 'keyB': 300}
文字列への変換
pprintの内容をファイルやログなどに出力したい場合等、文字列として欲しくなる場合があるかもしれません。pprintモジュールのpformat関数を使用するとpprint関数の出力と同様の内容を文字列で得ることができます。パラメータはpprint関数と同様であるため説明を割愛します。
from pprint import pformat
d = {}
text = pformat(d)
