Python 業務自動化 | ファイル・フォルダ自動化:基本操作 - フォルダ一覧取得

Python Python
スポンサーリンク

Pythonで「フォルダ一覧取得」をマスターしよう

ファイル一覧が取れるようになったら、次の一歩は「フォルダ(ディレクトリ)だけを一覧で取る」ことです。
業務自動化では「このフォルダの直下にあるサブフォルダを全部なめて処理したい」「日付ごとのフォルダを順番に処理したい」といった場面が本当によく出てきます。
ここでは、初心者向けにフォルダ一覧取得の基本から、実務でそのまま使えるテンプレートまで、丁寧に解説していきます。


フォルダ一覧取得の基本アイデア

「全部の中身」から「フォルダだけ」を選び出す

Python標準の os.listdir() は、指定した場所の「ファイル名とフォルダ名を全部」返してくれます。
つまり、最初の一歩は「とりあえず全部の名前をもらう」、次の一歩で「その中からフォルダだけを選び出す」という二段構えになります。

この「全部取ってから絞り込む」という考え方は、業務自動化全般でとても大事なパターンです。
データベースでもファイルでも、「取得 → フィルタ → 処理」という流れを意識できると、一気にコードが整理されていきます。

使う主役たち

フォルダ一覧取得でよく使うのは、次の3つです。

os.listdir(path)
指定したパス直下の「ファイル名+フォルダ名」の一覧をリストで返す。

os.path.join(base, name)
フォルダ名と名前をくっつけて「フルパス」を作る。

os.path.isdir(path)
そのパスが「フォルダかどうか」を真偽値で返す。

この3つを組み合わせるだけで、「フォルダ一覧取得」はほぼ完成します。


基本コード:指定フォルダ直下のフォルダ一覧を取得する

いちばんシンプルなフォルダ一覧コード

まずは「あるフォルダの直下にあるフォルダ名だけを一覧表示する」基本形からいきましょう。

import os

# 一覧を取りたい親フォルダのパス
dir_path = "data"  # 例:同じ階層にある data フォルダ

# 親フォルダの中身(ファイル+フォルダ)を全部取得
items = os.listdir(dir_path)

for name in items:
    # 親フォルダと名前を結合してフルパスにする
    full_path = os.path.join(dir_path, name)

    # そのパスが「フォルダかどうか」を判定
    if os.path.isdir(full_path):
        print(full_path)
Python

このコードを実行すると、data フォルダの直下にあるフォルダだけが、フルパスで表示されます。

ここで特に重要なのは、os.path.isdir() に渡しているのが「名前」ではなく「フルパス」だという点です。
名前だけを渡すと、「今いる場所(カレントディレクトリ)」基準で判定されてしまい、意図しない結果になることがあります。


重要ポイントを深掘りする

なぜ「フルパス」にする必要があるのか

os.listdir(dir_path) が返すのは、あくまで「そのフォルダの中に見えている名前のリスト」です。
例えば dir_path = "data" のとき、items["2024", "2025", "readme.txt"] のような単なる文字列のリストになります。

ところが、os.path.isdir()os.path.isfile() は、「どこの 2024 なのか」を知らないと正しく判定できません。
そこで os.path.join(dir_path, name) を使って、"data/2024" のような「場所付きの名前=フルパス」に変換してから判定します。

この「名前だけではなく、場所情報をくっつけてから判定する」という感覚は、ファイル操作全般で超重要です。
業務コードでも、ここを雑に書くと「たまたま動くけど、フォルダを移動したら壊れる」不安定なスクリプトになりがちです。

カレントディレクトリと相対パス・絶対パス

"data" のような書き方は「相対パス」です。
今いる場所(カレントディレクトリ)から見て、「そこから見える data フォルダ」を指しています。

一方で、Windowsなら r"C:\Users\user\Documents\data"、macOS / Linuxなら "/Users/user/Documents/data" のような書き方は「絶対パス」です。
業務で「毎回このフォルダを処理する」と決まっている場合は、絶対パスで書いてしまうことも多いです。

どちらを使うかは運用次第ですが、「相対パスを使うときは、スクリプトをどこで実行するかに依存する」という点は意識しておくと、トラブルを減らせます。


例題①:日付フォルダを一覧して処理するテンプレート

シナリオのイメージ

例えば、次のようなフォルダ構成を想像してください。

data/
├── 2024-01-01/
├── 2024-01-02/
├── 2024-01-03/
└── old/

この「日付フォルダ」を全部なめて、中にあるファイルを処理したい、というのはよくある業務パターンです。
まずは「日付フォルダの一覧を取る」部分だけをテンプレートとして書いてみます。

コード例と解説

import os

base_dir = "data"

# data直下の中身を取得
items = os.listdir(base_dir)

date_dirs = []

for name in items:
    full_path = os.path.join(base_dir, name)

    # フォルダだけを対象にする
    if not os.path.isdir(full_path):
        continue

    # ここでは「名前が '2024-' で始まるものだけ」を日付フォルダとみなす
    if name.startswith("2024-"):
        date_dirs.append(full_path)

# 見つかった日付フォルダを表示
for d in sorted(date_dirs):
    print(d)
Python

このテンプレートのポイントは、次のような流れになっていることです。

  1. 親フォルダの中身を os.listdir() で全部取る
  2. os.path.isdir() で「フォルダだけ」に絞る
  3. 名前のルール(ここでは "2024-" で始まる)でさらに絞る
  4. 必要なら sorted() で並び替えてから処理する

この「段階的に絞り込む」スタイルは、条件が増えても読みやすさを保ちやすいので、実務でもかなりおすすめの書き方です。


例題②:フォルダ一覧を使ってレポートを作る

シナリオのイメージ

次のような構成を考えます。

projects/
├── A/
├── B/
└── C/

それぞれのプロジェクトフォルダの中に、report.txt があるかどうかをチェックして、「どのプロジェクトにレポートがあるか」を一覧にしたい、というケースです。

ここで重要なのは、「まずプロジェクトフォルダの一覧を取る」→「その中身を確認する」という二段階構造です。

コード例と解説

import os

projects_root = "projects"

# プロジェクトフォルダ一覧を取得
project_names = [
    name
    for name in os.listdir(projects_root)
    if os.path.isdir(os.path.join(projects_root, name))
]

for name in sorted(project_names):
    project_dir = os.path.join(projects_root, name)
    report_path = os.path.join(project_dir, "report.txt")

    if os.path.exists(report_path):
        status = "レポートあり"
    else:
        status = "レポートなし"

    print(f"{name}: {status}")
Python

ここでは、少しだけ Python らしい書き方(リスト内包表記)を使っていますが、やっていることはシンプルです。

  1. os.listdir(projects_root) で「名前一覧」を取得
  2. os.path.isdir() で「フォルダだけ」に絞り込む
  3. そのフォルダの中に report.txt があるかを os.path.exists() で確認する

業務自動化では、「フォルダ単位で何かをチェックする」「フォルダ単位で処理を回す」というパターンが非常に多いので、このテンプレートは覚えておくとかなり使い回せます。


例題③:pathlibを使った、少しモダンなフォルダ一覧

pathlib.Pathで書くとどう変わるか

最近のPythonでは、os モジュールの代わりに pathlib を使う書き方もよく使われます。
Path オブジェクトは「パスを表す専用の型」で、メソッドチェーンで直感的に書けるのが特徴です。

フォルダ一覧取得を pathlib で書くと、次のようになります。

from pathlib import Path

base_dir = Path("data")

# data直下のフォルダだけを列挙
dir_list = [p for p in base_dir.iterdir() if p.is_dir()]

for d in sorted(dir_list):
    print(d)
Python

base_dir.iterdir() は、「そのフォルダ直下の中身(ファイル+フォルダ)」を順番に返してくれるイテレータです。
p.is_dir() で「フォルダかどうか」を判定し、フォルダだけをリストに集めています。

os 版とやっていることは同じですが、Path オブジェクトを使うと、パスの結合も base_dir / "sub" のように書けるので、慣れてくるとこちらの方が読みやすく感じる人も多いです。


よくあるつまずきポイントとコツ

サブフォルダの中まで見たいとき

os.listdir()Path.iterdir() は「直下だけ」を対象にします。
サブフォルダの中まで再帰的にたどりたい場合は、os.walk()Path.rglob() などを使うのが定番です。

ただ、いきなり再帰に飛び込むと混乱しやすいので、まずは「直下だけをきれいに扱える」状態になってから、次のステップとして学ぶのがおすすめです。

並び順に意味を持たせたいとき

os.listdir()iterdir() が返す順番は保証されません。
「名前順」「日付順」など、順番に意味を持たせたい場合は、必ず sorted() で並び替えてから処理するようにしましょう。

例えば、日付フォルダを古い順に処理したいなら、sorted(date_dirs) のようにしてからループを回す、という形です。


まとめ:フォルダ一覧取得は「業務自動化の骨組み」

フォルダ一覧取得は、それ単体では地味に見えますが、業務自動化では「骨組み」にあたる部分です。

  1. 親フォルダの中身を一覧で取得する
  2. フォルダだけに絞り込む(os.path.isdirPath.is_dir
  3. 必要に応じて名前のルールでさらに絞る
  4. 並び替えてから、フォルダ単位で処理を回す

この流れを自分のPC上の適当なフォルダで何度か試してみると、「あ、フォルダを相手にした自動化ってこう組み立てるんだな」という感覚がつかめてきます。

もしよければ、今あなたがよく使っている「案件ごとのフォルダ」や「日付ごとのバックアップフォルダ」を1つ決めて、そのパスを base_dir に入れて、上のテンプレートを動かしてみてください。
自分の実データが一覧でズラッと出てきた瞬間、「ここから何を自動化しようかな」という発想が自然と湧いてきます。

タイトルとURLをコピーしました