結論から言うと、長い処理は「入力を整える」「計算する」「出力用に整形する」のように段階ごとに分けると、読みやすく直しやすい形になります。

Pythonを書いていると、最初は1つの関数にまとめたほうが作りやすいことがあります。
ただ、条件分岐や繰り返しが増えてくると、どこで何をしているのかが見えにくくなります。
この記事では、長い処理をいきなり細かく分けるのではなく、流れを保ったまま小さな関数へ整理する方法を確認します。

この記事でわかること

  • 長い処理をどの単位で分割すると読みやすくなるか
  • 小さな関数に分けても全体の流れを失わない書き方
  • 実務で修正しやすい関数分割の考え方

完成コード

最初に必ず動くPythonコードを1つ示します。

sales_rows = [
    {"staff": "佐藤", "amount": "12000", "category": "書籍"},
    {"staff": "鈴木", "amount": "8000", "category": "文具"},
    {"staff": "佐藤", "amount": "5000", "category": "文具"},
]


def parse_sales(rows):
    parsed_rows = []
    for row in rows:
        parsed_rows.append(
            {
                "staff": row["staff"],
                "amount": int(row["amount"]),
                "category": row["category"],
            }
        )
    return parsed_rows


def summarize_by_staff(rows):
    summary = {}
    for row in rows:
        staff = row["staff"]
        summary.setdefault(staff, 0)
        summary[staff] += row["amount"]
    return summary


def build_report_lines(summary):
    lines = []
    for staff, total in sorted(summary.items()):
        lines.append(f"{staff}: {total}円")
    return lines


def create_sales_report(rows):
    parsed_rows = parse_sales(rows)
    summary = summarize_by_staff(parsed_rows)
    report_lines = build_report_lines(summary)
    return "\n".join(report_lines)


print(create_sales_report(sales_rows))

コードのポイント

このコードでは、売上レポートを作る処理を3段階に分けています。

  • 文字列の金額を数値に直す parse_sales()
  • 担当者ごとに合計する summarize_by_staff()
  • 表示用の行を組み立てる build_report_lines()

最後の create_sales_report() は、細かい処理を並べて全体の流れだけを見せています。
この形にすると、何をする処理かが上から順に追いやすくなります。

コードを順番に説明します

主要な処理を分けて説明します。

1. 入力データを先に扱いやすい形へ整えます

def parse_sales(rows):
    parsed_rows = []
    for row in rows:
        parsed_rows.append(
            {
                "staff": row["staff"],
                "amount": int(row["amount"]),
                "category": row["category"],
            }
        )
    return parsed_rows

元データでは amount が文字列になっていますが、このままだと集計しづらいです。
そこで最初に、計算しやすい形へそろえています。

長い処理を分割するときは、最初に「前処理だけを担当する関数」があると全体が整理しやすいです。
あとで入力形式が変わっても、この関数を直せば済む形になります。

2. 集計処理は計算だけに集中させます

def summarize_by_staff(rows):
    summary = {}
    for row in rows:
        staff = row["staff"]
        summary.setdefault(staff, 0)
        summary[staff] += row["amount"]
    return summary

この部分は、担当者ごとの売上合計を作る役割です。
入力の整形や表示用の文字列作成まで一緒にすると、関数の責務が広がって読みづらくなります。

分割するときは、「この関数は何を返すのか」を1つに決めるのが大切です。
ここでは集計結果の辞書だけを返しているので、動作を確認しやすくなります。

3. 最後に表示用の形へ整えて流れをまとめます

def build_report_lines(summary):
    lines = []
    for staff, total in sorted(summary.items()):
        lines.append(f"{staff}: {total}円")
    return lines


def create_sales_report(rows):
    parsed_rows = parse_sales(rows)
    summary = summarize_by_staff(parsed_rows)
    report_lines = build_report_lines(summary)
    return "\n".join(report_lines)

レポートの表示形式は、集計ルールとは別の役割です。
そのため、表示用の行を作る関数を分けておくと、出力形式を変えるときに直しやすくなります。

create_sales_report() のような関数は、細かい処理を書く場所というより、全体の手順を書く場所です。
長い関数を分割するときは、このような司令塔になる関数を1つ残すと、処理の見通しがよくなります。

実務で使うときのポイント

実務では、関数を小さくすればするほどよいわけではありません。
大事なのは、変更されやすい単位で分けることです。

  • 入力形式が変わりやすい処理、集計ルールが変わりやすい処理、表示形式が変わりやすい処理は分けておくと保守しやすいです
  • 分割後の関数は、引数と戻り値を見れば役割がわかる形にすると読みやすいです
  • 全体の流れをまとめる関数を1つ置くと、呼び出し順が見えやすくなります
  • 途中で何度も同じ値変換をしているなら、その段階を独立させるとバグを減らしやすいです

特に業務コードでは、「CSVの読み込み」「データ整形」「集計」「保存」のように段階がはっきりしていることが多いです。
この境目で分けると、テストしやすく、差し替えもしやすくなります。

よくある勘違い・注意点

  • 1つの関数を数行ごとに分けると、かえって処理の流れが追いにくくなることがあります
  • 関数を分けても、引数が多すぎると扱いづらさはあまり改善しません
  • 途中で print() を混ぜると、計算処理と表示処理が再び混ざりやすくなります
  • 分割したあとに関数名が曖昧なままだと、役割が整理できていない可能性があります

まとめ

  • 長い処理は、前処理、計算、表示のように段階ごとに分けると整理しやすいです
  • 小さな関数は1つの戻り値と1つの役割に集中させると読みやすくなります
  • 全体の流れを書く関数を残すと、分割後も処理の順番を追いやすいです
  • 実務では、変更されやすい境目で分けると保守しやすくなります