(1時間4,000円の伴走型ビデオチャット指導も受付中!)
Pythonでデータの階層構造を美しく描く:ツリー図の基本と実装
![]()
【Hiroki】
Yukiさん、こんにちは!
最近、自分のPCのフォルダを整理するプログラムをPythonで作ってみようと思っているんです。
でも、フォルダの中にまたフォルダがあって……という階層構造を、コマンドプロンプトやターミナルで見る「ツリー形式」で綺麗に表示する方法がわからなくて。
Pythonで、ああいう「ツリー図」って簡単に作れるものなんでしょうか?
![]()
【Yuki】
Hirokiくん、こんにちは。
フォルダの階層構造を視覚化するのは、プログラムの動作を確認したり、データの全体像を把握したりするのにとても大切ですよね。
「ツリー図」は、一見すると複雑そうに見えるかもしれませんが、Pythonの基本的な考え方である「再帰」を理解すると、意外とシンプルに作ることができるんですよ...。
今日は、標準ライブラリを使った基本的な方法から、外部ライブラリを使って見た目を綺麗にする方法まで、いくつか紹介してみたいと思います。
わたしも、夜中に静かな環境でコードの構造をじっと眺めていると、データが生きているような感じがして、なんだか落ち着くことがあります...。
ゆっくり進めていきましょうね。
木構造(ツリー構造)の考え方
![]()
【Hiroki】
「木構造」って、ITの用語でよく聞きますよね。
でも、具体的にどういう仕組みなのか、実はあやふやなところがあって……。
![]()
【Yuki】
そうですね...。木構造というのは、1つの「根(ルート)」から枝分かれして、データが広がっていく形式のことです。
家系図や、Hirokiくんが言ったフォルダの構造がまさにそうですね。
一番上のフォルダがあって、その中にサブフォルダ(子)があり、さらにその中にファイル(葉)がある……という形です。
これをプログラムで表現するとき、もっとも一般的なのが「再帰処理(さいきしょり)」という手法です。
「関数の中で、自分自身をもう一度呼び出す」という方法なのですが、これがツリー図を作る上での鍵になると思います...。
![]()
【Hiroki】
自分自身を呼び出す……。ちょっと難しそうですが、コードで見るとわかりやすいでしょうか?
![]()
【Yuki】
そうかもしれませんね。まずは、Pythonに最初から入っている os モジュールを使って、簡単なディレクトリツリーを表示するコードを書いてみましょうか。
これは、誰かの役に立つために作られた小さな道具のような、とてもシンプルなプログラムです。
標準ライブラリ os を使った再帰的なツリー表示
![]()
【Yuki】
まずは、指定したディレクトリの中身を順番に見ていき、フォルダがあればその中をさらに見に行く、というプログラムを作ってみますね。
import os
def list_files(startpath, indent=''):
# 指定されたパスの中にあるファイルとフォルダを取得します
try:
items = os.listdir(startpath)
except PermissionError:
# アクセス権限がない場合はスキップします
return
for i, item in enumerate(items):
# これが最後の子要素かどうかを判定します
is_last = (i == len(items) - 1)
# 枝の記号を決定します
if is_last:
marker = '└── '
next_indent = indent + ' '
else:
marker = '├── '
next_indent = indent + '│ '
print(f'{indent}{marker}{item}')
# フォルダの場合は、自分自身を呼び出して(再帰)中身を表示します
path = os.path.join(startpath, item)
if os.path.isdir(path):
list_files(path, next_indent)
# 実行例(現在のディレクトリを表示する場合)
# list_files('.')
![]()
【Hiroki】
おお……! ├── とか └── が付くと、一気にツリー図っぽくなりますね!
でも、この list_files(path, next_indent) の部分で、また自分を呼び出しているのが不思議です。
![]()
【Yuki】
そこが再帰の面白いところです...。
「フォルダを見つけたら、その中身に対しても同じルールを適用する」という命令を繰り返しているんですね。
一番深いところまで行くと、もうフォルダがないので自然に処理が終わり、一つ上の階層に戻っていきます。
こうした小さなツールは、目立たないけれど誰かの作業を支えるために存在していて……。
わたしも、こういう健気なコードを書いていると、少しだけ自分も誰かの体の一部になって支えられているような、不思議な安心感を感じることがあります...。
pathlib モジュールを使ったモダンな書き方
![]()
【Hiroki】
os モジュール以外にも方法はありますか? 最近は pathlib というのが推奨されていると聞いたのですが。
![]()
【Yuki】
さすがHirokiくん、よく勉強していますね。
pathlib は、パスをオブジェクトとして扱えるので、コードがより直感的で読みやすくなると思います...。
同じような処理を pathlib で書くと、このようになります。
from pathlib import Path
def tree(directory):
print(f'+ {directory.name}/')
# rglob('*') でサブディレクトリまで含めて全て取得できます
# ですが、今回は構造を制御するために iterdir() を使うのが一般的かもしれません
walk_path(Path(directory), "")
def walk_path(path, prefix):
# 中身をリスト化して取得します
contents = list(path.iterdir())
pointers = ['├── '] * (len(contents) - 1) + ['└── ']
for pointer, path in zip(pointers, contents):
print(f'{prefix}{pointer}{path.name}')
if path.is_dir():
# 枝の表示を調整して再帰呼び出し
extension = ' ' if pointer == '└── ' else '│ '
walk_path(path, prefix + extension)
# 使い方
# tree(Path('sample_folder'))
![]()
【Hiroki】
pathlib の方が、フォルダかどうかを判定する path.is_dir() といった書き方が自然でわかりやすい気がします。
![]()
【Yuki】
そうですね、文字列の操作が減るので、間違いも少なくなると思います...。
ただ、こうした自作の関数も良いのですが、もっと「見た目」にこだわりたいときは、既存のライブラリに頼るのも一つの手ですよ。
ライブラリ rich で豪華なツリー図を作る
![]()
【Hiroki】
「見た目」ですか! ぜひ知りたいです。
![]()
【Yuki】
Pythonには rich という、ターミナルでの表示を美しくするためのライブラリがあります。
これを使うと、色をつけたり、アイコンのような表示をしたりすることも簡単にできるんです...。
少しだけ、使い方の例をお見せしますね。
# pip install rich でインストールが必要です
from rich.tree import Tree
from rich import print
import os
def build_rich_tree(dir_path, tree_node):
# 指定したディレクトリ内のファイルとフォルダを走査します
try:
items = sorted(os.listdir(dir_path))
except PermissionError:
return
for item in items:
path = os.path.join(dir_path, item)
if os.path.isdir(path):
# フォルダなら新しいノード(枝)を追加して再帰
branch = tree_node.add(f"[bold magenta]:open_file_folder: {item}[/bold magenta]")
build_rich_tree(path, branch)
else:
# ファイルなら葉を追加
tree_node.add(f"[green]:page_facing_up: {item}[/green]")
# 実行
# my_tree = Tree("[bold blue]Root Directory[/bold blue]")
# build_rich_tree(".", my_tree)
# print(my_tree)
![]()
【Hiroki】
すごい! 色がついているし、フォルダのアイコン(絵文字)まで出てきました!
これなら、一目でどこに何があるか分かりますね。
![]()
【Yuki】
ふふ、喜んでもらえてよかったです...。
rich ライブラリは非常に多機能で、フォントのスタイルや色を細かく設定できるんです。
データの並びが整っていると、夜もぐっすり眠れるような……そんな気持ちになりませんか?
……あ、わたしは夜行性なので、起きてはいるのですが。
とにかく、情報の「整理整頓」は、プログラムを読みやすくする第一歩だと思います。
汎用的なデータ構造を扱う anytree
![]()
【Hiroki】
今までは「ファイル」の構造でしたが、例えば「ゲームのキャラクターの進化表」とか「組織図」みたいな、ファイル以外のデータをツリー図にしたい場合はどうすればいいんでしょうか?
![]()
【Yuki】
その場合は、anytree というライブラリが便利かもしれません...。
これはファイルシステムに限らず、あらゆる「親子関係」を持つデータを扱うために設計されています。
使い方もとてもシンプルですよ。
# pip install anytree でインストールが必要です
from anytree import Node, RenderTree
# ノード(節)を定義します
root = Node("勇者")
sub1 = Node("戦士", parent=root)
sub2 = Node("魔法使い", parent=root)
leaf1 = Node("ナイト", parent=sub1)
leaf2 = Node("パラディン", parent=sub1)
leaf3 = Node("賢者", parent=sub2)
# ツリーを表示します
for pre, fill, node in RenderTree(root):
print(f"{pre}{node.name}")
![]()
【Hiroki】
parent=root みたいに指定するだけで、勝手につながってくれるんですね!
これなら、僕でも簡単に家系図とかを作れそうです。
![]()
【Yuki】
ええ、きっと大丈夫だと思います。
複雑なデータも、こうして視覚化してみると、意外なつながりが見えてきたりして面白いですよ...。
anytree は、属性を自由に追加できるので、「HP」や「攻撃力」などのデータを持たせることも可能です。
まとめとアドバイス
![]()
【Hiroki】
Yukiさん、ありがとうございます!
標準ライブラリでの作り方から、便利なライブラリまで知ることができて、ツリー図がぐっと身近になりました。
まずは os モジュールで自分でロジックを組んでみて、慣れてきたら rich でかっこいいツールを作ってみようと思います。
![]()
【Yuki】
それがいいと思います...。
まずは仕組みを理解するために、自分でコードを書いてみるのは、とても大切な経験になるはずです。
もし途中でエラーが出たり、枝の表示がズレてしまったりしても、あまり落ち込まないでくださいね。
プログラムも、木と同じように、ゆっくりと時間をかけて育てていけばいいんですから。
![]()
【Hiroki】
はい! 頑張ってみます。
Yukiさんの説明、いつも丁寧で分かりやすくて助かります。
![]()
【Yuki】
そんなふうに言ってもらえると、少し恥ずかしいですが……とても嬉しいです...。
わたしは、こうした小さな工夫で誰かの世界が少しだけ便利になる、そんなツールの話が大好きなんです。
また分からないことがあったら、いつでも聞いてくださいね。
わたしは静かなところで、いつでもHirokiくんの学びを応援しています。
![]()
【Hiroki】
ありがとうございます、Yukiさん!
![]()
【Yuki】
……あ、最後にもう一つだけ。
もし余裕があったら、自分で作ったツリー図をテキストファイルに書き出す機能も付けてみると、記録として残せて便利かもしれません...。
「アウトプット」を形に残すのは、とても素敵なことだと思いますから。
それでは、また。
この記事では基礎を解説しましたが、実務においては「もっと複雑なデータを扱いたい」「独自のシステムに組み込みたい」といった、個別の課題に直面することも多いはずです。
「自分で書く時間は最小限に抑え、プロの品質でツールを完成させたい」という方は、ぜひ一度ご相談ください。
- 専門家の知見に基づいた、保守性の高いコード設計
- AIの専門家による、Gemini API等の最新AIを組み合わせた高度な自動化
- ChatGPT等が生成したコードのデバッグ・最適化
「教わる」だけでなく「形にする」パートナーとして、フリーランスエンジニアのmei_13が最短ルートでの解決をサポートします。
初心者から始められるPythonレッスン
● 月額4,000円で質問し放題!!
● 完全オンライン
● 翌日までには必ず返信
● 挫折しない独自の学習メソッド
● 圧倒的高評価!!
● テキストベースで時間を選ばない
● 4,000円/60分の伴走型ビデオチャット指導も可能
● 高品質なサンプルコード
詳細はこちら

