Pythonのpprintの使い方(リストや辞書を整形して出力)
Pythonの標準ライブラリであるpprintモジュールを使うと、リスト(list
型)や辞書(dict
型)などのオブジェクトをきれいに整形して出力・表示したり、文字列(str
型オブジェクト)に変換したりすることができる。pprintは「pretty-print」の略。
サンプルコードでは、以下のようにpprintモジュールをimport
し、辞書を要素とするリストを例に説明する。標準ライブラリなので追加でインストールする必要はない。
import pprint
l = [{'Name': 'Alice XXX', 'Age': 40, 'Points': [80, 20]},
{'Name': 'Bob YYY', 'Age': 20, 'Points': [90, 10]},
{'Name': 'Charlie ZZZ', 'Age': 30, 'Points': [70, 30]}]
通常のprint()
(組み込み関数)については以下の記事を参照。
リストや辞書ではなく長い文字列を整形(折り返し・省略)して出力するにはtextwrapモジュールが便利。
pprintの基本的な使い方
通常のprint()
関数ではリストや辞書の要素が改行されることなく1行で出力される。
print(l)
# [{'Name': 'Alice XXX', 'Age': 40, 'Points': [80, 20]}, {'Name': 'Bob YYY', 'Age': 20, 'Points': [90, 10]}, {'Name': 'Charlie ZZZ', 'Age': 30, 'Points': [70, 30]}]
pprint.pprint()
を使うと、以下のようにリストの要素ごとに改行されて見やすくなる。
pprint.pprint(l)
# [{'Age': 40, 'Name': 'Alice XXX', 'Points': [80, 20]},
# {'Age': 20, 'Name': 'Bob YYY', 'Points': [90, 10]},
# {'Age': 30, 'Name': 'Charlie ZZZ', 'Points': [70, 30]}]
どこで改行されるかは以下で説明する引数の設定によって決まる。
なお、上の例のように、辞書の要素はキーの順番でソートされる。Python3.8で追加された引数sort_dicts
をFalse
とする(デフォルトはTrue
)と元の辞書の順番のままとなるが、それより前のバージョンでは常にソートされるので注意。
出力するのではなく文字列(str
型オブジェクト)に変換したい場合は後述のpprint.pformat()
を使う。
出力幅(文字数)を指定: 引数width
出力する幅(文字数)を引数width
で指定できる。
1行が指定の文字数に収まるようにリストや辞書の要素で改行される。デフォルトはwidth=80
。
pprint.pprint(l, width=40)
# [{'Age': 40,
# 'Name': 'Alice XXX',
# 'Points': [80, 20]},
# {'Age': 20,
# 'Name': 'Bob YYY',
# 'Points': [90, 10]},
# {'Age': 30,
# 'Name': 'Charlie ZZZ',
# 'Points': [70, 30]}]
大きい値を指定すると、改行が挿入されずprint()
と同様の出力になる。
pprint.pprint(l, width=200)
# [{'Age': 40, 'Name': 'Alice XXX', 'Points': [80, 20]}, {'Age': 20, 'Name': 'Bob YYY', 'Points': [90, 10]}, {'Age': 30, 'Name': 'Charlie ZZZ', 'Points': [70, 30]}]
改行されるのはリストや辞書の要素ごとで、辞書のキーkey
と値value
で改行されたり、数値の途中で改行されたりはしない。このため、必ずwidth
で指定した文字数の幅に収まるわけではない。
文字列は単語ごと(スペースごと)に改行されるので注意。
pprint.pprint(l, width=1)
# [{'Age': 40,
# 'Name': 'Alice '
# 'XXX',
# 'Points': [80,
# 20]},
# {'Age': 20,
# 'Name': 'Bob '
# 'YYY',
# 'Points': [90,
# 10]},
# {'Age': 30,
# 'Name': 'Charlie '
# 'ZZZ',
# 'Points': [70,
# 30]}]
出力する要素の深さを指定: 引数depth
出力する要素の深さを引数depth
で指定できる。ここでいう深さは入れ子になったデータの深さのこと。
指定した値より深い要素は省略記号...
で出力される。
pprint.pprint(l, depth=1)
# [{...}, {...}, {...}]
pprint.pprint(l, depth=2)
# [{'Age': 40, 'Name': 'Alice XXX', 'Points': [...]},
# {'Age': 20, 'Name': 'Bob YYY', 'Points': [...]},
# {'Age': 30, 'Name': 'Charlie ZZZ', 'Points': [...]}]
デフォルトはdepth=None
で、すべての要素が省略されず出力される。
width
を組み合わせることも可能。depth
で指定するのはあくまでもデータ構造としての深さで、行数ではない。どこで改行されるかはwidth
で指定する文字数によって決まる。
pprint.pprint(l, depth=2, width=40)
# [{'Age': 40,
# 'Name': 'Alice XXX',
# 'Points': [...]},
# {'Age': 20,
# 'Name': 'Bob YYY',
# 'Points': [...]},
# {'Age': 30,
# 'Name': 'Charlie ZZZ',
# 'Points': [...]}]
インデント幅を指定: 引数indent
インデント幅を引数indent
で指定できる。デフォルトはindent=1
。
pprint.pprint(l, indent=4, width=4)
# [ { 'Age': 40,
# 'Name': 'Alice '
# 'XXX',
# 'Points': [ 80,
# 20]},
# { 'Age': 20,
# 'Name': 'Bob '
# 'YYY',
# 'Points': [ 90,
# 10]},
# { 'Age': 30,
# 'Name': 'Charlie '
# 'ZZZ',
# 'Points': [ 70,
# 30]}]
改行を最小限にする: 引数compact
デフォルトでは出力幅width
に収まらない場合はリストや辞書のすべての要素で改行される。
l_long = [list(range(10)), list(range(100, 110))]
print(l_long)
# [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [100, 101, 102, 103, 104, 105, 106, 107, 108, 109]]
pprint.pprint(l_long, width=40)
# [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
# [100,
# 101,
# 102,
# 103,
# 104,
# 105,
# 106,
# 107,
# 108,
# 109]]
引数compact
をTrue
とすると出力幅width
に収まらない分だけが改行される。要素数の多いリストなどがある場合はcompact=True
のほうが見やすい。
pprint.pprint(l_long, width=40, compact=True)
# [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
# [100, 101, 102, 103, 104, 105, 106,
# 107, 108, 109]]
文字列に変換: pprint.pformat()
辞書やリストはstr()
で文字列(str
型)に変換できる。
この場合、通常のprint()
関数での出力のようにリストや辞書の要素が改行されることなく1行の文字列となる。
s_normal = str(l)
print(s_normal)
# [{'Name': 'Alice XXX', 'Age': 40, 'Points': [80, 20]}, {'Name': 'Bob YYY', 'Age': 20, 'Points': [90, 10]}, {'Name': 'Charlie ZZZ', 'Age': 30, 'Points': [70, 30]}]
print(type(s_normal))
# <class 'str'>
pprint.pprint()
ではなくpprint.pformat()
を使うと適宜改行が挿入されて整形された文字列(str
型オブジェクト)として取得できる。
s_pp = pprint.pformat(l)
print(s_pp)
# [{'Age': 40, 'Name': 'Alice XXX', 'Points': [80, 20]},
# {'Age': 20, 'Name': 'Bob YYY', 'Points': [90, 10]},
# {'Age': 30, 'Name': 'Charlie ZZZ', 'Points': [70, 30]}]
print(type(s_pp))
# <class 'str'>
pprint.pformat()
の引数はpprint.pprint()
と共通。
s_pp = pprint.pformat(l, depth=2, width=40, indent=2)
print(s_pp)
# [ { 'Age': 40,
# 'Name': 'Alice XXX',
# 'Points': [...]},
# { 'Age': 20,
# 'Name': 'Bob YYY',
# 'Points': [...]},
# { 'Age': 30,
# 'Name': 'Charlie ZZZ',
# 'Points': [...]}]
例: 二次元配列(リストのリスト)を整形して表示
pprint
は二次元配列(リストのリスト)を表示する場合に使うと便利。
通常のprint()
関数だと見にくいが、pprint
を使うと見やすい。
l_2d = [list(range(10)), list(range(10)), list(range(10))]
print(l_2d)
# [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
pprint.pprint(l_2d)
# [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]
上述のように、どこで改行するかは引数width
で指定する文字数によって決まる。
要素数が少ない場合はデフォルトの出力幅width=80
に収まるので改行されない。
l_2d = [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
print(l_2d)
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
pprint.pprint(l_2d)
# [[0, 1, 2], [3, 4, 5], [6, 7, 8]]
改行して表示したい場合はwidth
を適宜指定する。
pprint.pprint(l_2d, width=20)
# [[0, 1, 2],
# [3, 4, 5],
# [6, 7, 8]]
文字列として取得したい場合はpprint.pformat()
。
s = pprint.pformat(l_2d, width=20)
print(s)
# [[0, 1, 2],
# [3, 4, 5],
# [6, 7, 8]]
print(type(s))
# <class 'str'>