🛸
深いネストが読めないあなたへ -- pprint を超える setprint の世界
A hands-on guide to structural debugging with setprint
「整形ツールを使う時点で、データはもう単純じゃない」
pprint は便利。でも、それは“簡単なデータ”のうちだけだった。
深くネストされたリスト、型が混ざった辞書、画像のようなNumPy配列…。
pprint は途中で切れ、構造は見えず、バグの兆候も埋もれてしまう。
名前は SetPrint。
そこで私は、「本当に見える整形ツール」 を作ることにした。この記事では
pprint
/setprint
を並べて比較- 画像データ・混同行列を例に“構造が見える快感”を体験
- ベンチ結果と現場で効く 5 つの Tips
0. この記事で使う共通データ
import numpy as np
data = {
"users": [
{"name": "Alice", "scores": np.array([95, 88, 76])},
{"name": "Bob", "scores": np.array([72, 85, 90])}
],
"meta": {"created": "2025-04-23", "version": 1.2}
}
これを pprint・setprint で整形し、違いを コードブロック で一発比較します。
📎 この記事のデータを Colab でそのまま試せます タップ ▵
🖱️ インストール不要、keep_settings
も自由に書き換えてOK!
(Colabを利用するには、Googleアカウントが必要です。)
1. 構造が一目でわかる出力
== pprint ==
{'meta': {'created': '2025-04-23', 'version': 1.2},
'users': [{'name': 'Alice', 'scores': array([95, 88, 76])},
{'name': 'Bob', 'scores': array([72, 85, 90])}]}
== setprint ==
keep_settings
['y', 'y', 'y', 'y']
--------------------------------------------------------
◆dict
├── users:►list
│ ├───── -------. ◆dict
│ │ ├───────── name : Alice
│ │ └───────── scores:>ndarray
│ │ ├─────── 95
│ │ ├─────── 88
│ │ └─────── 76
│ └───── -------. ◆dict
│ ├───────── name : Bob
│ └───────── scores:>ndarray
│ ├─────── 72
│ ├─────── 85
│ └─────── 90
└── meta :◆dict
├───── created:2025-04-23
└───── version: 1.2
--------------------------------------------------------
2. 画像データも 3 行で読める
| [Block 1] : [Block 2] : [Block 3] |
| >ndarray : >ndarray ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ : >ndarray ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ ┊ |
| ├──── >ndarray ───┬────────────────────┬────────────────────┐ : ├──── >ndarray ───┬────────────────────┬────────────────────┐ ┊ ┊ ┊ : ├──── >ndarray [ >ndarray [ 255 0 4 ] >ndarray [ 255 85 0 ] >ndarray [ 255 170 0 ] ] |
| │ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ : │ ┊ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ : ├──── >ndarray [ >ndarray [ 170 255 0 ] >ndarray [ 85 255 0 ] >ndarray [ 0 255 4 ] ] |
| │ 255 0 4 255 85 0 255 170 0 : │ ┊ ┊ 255 0 4 ┊ 255 85 0 ┊ 255 170 0 : └──── >ndarray [ >ndarray [ 0 170 255 ] >ndarray [ 0 85 255 ] >ndarray [ 4 0 255 ] ] |
| ├──── >ndarray ───┬────────────────────┬────────────────────┐ : ├──── >ndarray ───┬────────────────────┬────────────────────┐ ┊ ┊ ┊ : |
| │ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ : │ ┊ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ : |
| │ 170 255 0 85 255 0 0 255 4 : │ ┊ ┊ 170 255 0 ┊ 85 255 0 ┊ 0 255 4 : |
| └──── >ndarray ───┬────────────────────┬────────────────────┐ : └──── >ndarray ───┬────────────────────┬────────────────────┐ ┊ ┊ ┊ : |
| >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ : ┊ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ >ndarray ─┬───┬───┐ : |
| 0 170 255 0 85 255 4 0 255 : ┊ ┊ 0 170 255 ┊ 0 85 255 ┊ 4 0 255 : |
3. 混同行列 (4 × 4) も“テキストヒートマップ”
cm = np.array([[50, 2, 0, 0],
[ 3, 45, 1, 0],
[ 0, 4, 60, 5],
[ 0, 0, 6, 70]])
keep_settings
['y', 'x']
------------------------------
>ndarray
├──── >ndarray ┬──┬──┬──┐
│ 50 2 0 0
├──── >ndarray ┬──┬──┬──┐
│ 3 45 1 0
├──── >ndarray ┬──┬──┬──┐
│ 0 4 60 5
└──── >ndarray ┬──┬──┬──┐
0 0 6 70
------------------------------
ヒートマップ画像と並べれば「画素値 ↔ 行列要素」の対応がすぐ分かります。
4. ライブラリ別ベンチマーク(10 回平均)
ライブラリ | 実行時間 [ms] | 構造可視性 |
---|---|---|
pprint | 1.5 | ★☆☆☆☆ |
rich.pretty | 3.2 | ★★☆☆☆ |
setprint | 4.8 | ★★★★★ |
±数 ms のオーバーヘッドで 構造が丸見えなら圧倒的にペイ。
5. 👀 たった1つの関数(メソッド)だけでOK!
setprint
に使うべき関数 (正確にはメソッド) は1つだけ。名前は set_collection()
。この中に整形の全機能が詰まってます。
「難しいこと考えず、これを呼ぶだけ」でネストの深いリストも NumPy も全部見える化!
from setprint import SetPrint
# === 整形対象のデータを渡してインスタンス生成 ===
datas = [
[[1, 2, 3], [4, 5, 6]],
[[7, 8, 9], [10, 11, 12]]
]
list_data = SetPrint(datas)
# === 展開の方向やフォーマットの設定 ===
keep_settings = {
1: 'x', # 第1次元をX方向に展開
3: 'yf', # 第3次元をY方向 + flatten
4: 'f' # 第4次元はフラット化
}
# === 整形処理の実行 ===
format_texts = list_data.set_collection(
route='SLIM', # 表示スタイル:細い線でコンパクトに
y_axis=False, # Y軸のガイド線は非表示
keep_settings=keep_settings,
verbose=False # 処理状況の表示はオフ
)
# === 結果の表示やファイル保存 ===
with open('output.txt', 'w') as f:
for line in format_texts:
f.write(line + '\n')
# --- 補足 ---
# ✅ 同じデータに対しては、インスタンスをそのまま使い回して
# keep_settings を変えて何度でも整形可能です。
#
# 🔄 データそのもの(例:datas)を変えたい場合は、
# SetPrint(new_data) を使って新しくインスタンスを作ってください。
6. 実践 Tips 5 連発
-
展開したい次元は
keep_settings
で柔軟に指定可能- たとえば
{1: 'x', 3: 'yf', 4: 'f'}
のように、各次元に展開方向を割り当てられます。 -
'x'
:X方向に展開 -
'y'
:Y方向に展開(ネストを維持) -
'yf'
:Y方向に展開しつつ中身をフラット化(flatten) -
'f'
:'yf'
実行後の次元に対して適用される追加フラット化。単独では機能しません
- たとえば
-
構造の柱として Y軸ガイド線を表示(
y_axis=True
)- ネストが深くても、縦の罫線で構造を見失わずに追うことができます。
-
y_axis=False
にすればオフにもできる柔軟設計です。
-
整形結果は文字列リストで返されるため、ファイル保存やテキスト表示にそのまま使える
-
for line in format_texts:
のように各行を書き出すだけでログとして活用できます。
-
-
構造混在のデータでも可視化が破綻しない
-
dict
+list
+ndarray
のような複合構造でも、それぞれを展開・視覚化できます。
-
-
出力スタイルは
route='SLIM'
などで切り替え可能(簡潔モード)- 今後の拡張を見越しつつも、すでにシンプルな表示モードに対応しています。
7. まとめ ― “インデント地獄”からの解放
- pprint は「値を整列」
- setprint は「構造を可視化」
- NumPy / 多次元 / ネストが深いデータのデバッグ、レビュー、ログが劇的にラクに。
まずは 30 秒
pip install setprint
動いたら ⭐ をポチッと! バグ報告・機能要望・PR も大歓迎です 🚀
Appendix B ─ 参考リンク
- GitHub https://github.com/mtur2007/SetPrint
- PyPI https://pypi.org/project/setprint/
- Colab デモ https://colab.research.google.com/drive/1Qs3xgB7pWxmOPtsWonyj29r1VMDwo6KF?usp=sharing
Enjoy structural debugging!
Discussion