関数は処理に名前を付けて再利用するしくみです。本記事では関数の基本(引数・戻り値・デフォルト引数・キーワード引数)を整理し、関数に分ける理由を株価分析の例で説明します。

目次

  1. 関数の基本形
  2. なぜ関数に分けるのか
  3. 戻り値がない関数
  4. デフォルト引数 — 値を省略可能にする
  5. キーワード引数 — 名前で渡す
  6. 可変長引数 — *args と **kwargs
  7. 関数を組み合わせる
  8. 引数を変更しない設計
  9. docstring — 関数の説明を書く

関数の基本形

関数は def キーワードで定義します。

def average(values: list[float]) -> float:
return sum(values) / len(values)
prices = [2900, 2925, 2880, 2910, 2945]
print(average(prices)) # 2912.0

構成要素は次のとおりです。

  • def の後ろに 関数名 を書く(スネークケースが慣例)
  • カッコの中が 引数 の宣言
  • -> の後ろが 戻り値の型ヒント(省略可、#3-11「型ヒントの基本」 で詳述)
  • 関数の末尾は return で値を返す

なぜ関数に分けるのか

同じ処理を複数の場所で書くと、修正のときに必ず食い違いが起きます。関数にまとめる理由は次の 3 点です。

  • 再利用: 同じ処理を一行で呼び出せる
  • テスト容易性: 入力と出力の関係だけを確認できる
  • 可読性: 名前の付いた処理として読めるため、本筋を追いやすい

戻り値がない関数

何かを表示するだけの関数など、戻り値がない場合もあります。return を省略すると None が返ります。

def print_summary(prices: list[float]) -> None:
print(f"件数: {len(prices)}")
print(f"平均: {sum(prices) / len(prices):.2f}")
print_summary([2900, 2925, 2880])

デフォルト引数 — 値を省略可能にする

引数に既定値を持たせると、呼び出し側で省略できます。

def moving_average(values: list[float], window: int = 5) -> list[float]:
if len(values) < window:
return []
return [
sum(values[i - window + 1 : i + 1]) / window
for i in range(window - 1, len(values))
]
prices = [100, 102, 101, 103, 105, 107, 110]
print(moving_average(prices)) # 既定 (5 日)
print(moving_average(prices, 3)) # 3 日に変更

「ほとんどの場合は 5 日窓だが、たまに 3 日窓にもしたい」というケースに向いています。

キーワード引数 — 名前で渡す

引数は順番だけでなく、名前=値 の形でも渡せます。

def fetch_prices(ticker: str, start: str, end: str) -> list[float]:
# 実際は API 呼び出しなどを行う
return []
# 位置引数
fetch_prices("7203", "2026-04-01", "2026-04-30")
# キーワード引数(順番を変えても良い)
fetch_prices(ticker="7203", end="2026-04-30", start="2026-04-01")

引数が増えてくると、キーワード引数のほうが意図が明確になります。

可変長引数 — *args と **kwargs

引数の数が決まらないときは、*args(タプル)や **kwargs(辞書)で受け取ります。

def total(*values: float) -> float:
return sum(values)
print(total(1, 2, 3)) # 6
print(total(2900, 2925, 2880)) # 8705
def describe(**fields: str) -> None:
for key, value in fields.items():
print(f"{key}: {value}")
describe(ticker="7203", name="トヨタ自動車", market="プライム")

主にライブラリ側で使われる書き方ですが、自分で書くケースもあります。

関数を組み合わせる

小さな関数を組み合わせて大きな処理を作ると、見通しが良くなります。

def daily_returns(prices: list[float]) -> list[float]:
return [
(curr - prev) / prev
for prev, curr in zip(prices[:-1], prices[1:])
]
def average(values: list[float]) -> float:
return sum(values) / len(values)
def average_return(prices: list[float]) -> float:
return average(daily_returns(prices))
prices = [100, 102, 101, 103, 105]
print(f"{average_return(prices):.4f}") # 0.0123

「日次リターンを計算する」「平均を取る」という 2 つの責務を分けたことで、それぞれを単独でテストできます。

引数を変更しない設計

関数の中でリストや辞書を書き換えると、呼び出し元の値も変わってしまいます。

def append_zero_bad(values: list[float]) -> list[float]:
values.append(0) # 引数を直接変更
return values
original = [1, 2, 3]
result = append_zero_bad(original)
print(original) # [1, 2, 3, 0] — 元のリストも変わってしまう

新しいリストを返す書き方に直します。

def append_zero_safe(values: list[float]) -> list[float]:
return values + [0]
original = [1, 2, 3]
result = append_zero_safe(original)
print(original) # [1, 2, 3] — 元は無傷
print(result) # [1, 2, 3, 0]

「引数は読み取り専用に扱う」のを基本姿勢にすると、思わぬバグが減ります。

docstring — 関数の説明を書く

関数の冒頭に文字列を書くと、それが説明として扱われます。

def average(values: list[float]) -> float:
"""値のリストから単純平均を計算する。
引数:
values: 数値のリスト。空リストは渡さない。
戻り値:
単純平均。
"""
return sum(values) / len(values)
print(average.__doc__)

生成AI に関数を読んでもらうとき、docstring があると意図が伝わりやすくなります。

生成AI へのプロンプト例

関数の設計を生成AI に相談する例です。

次の責務を持つ Python 関数を書いてください。
- 名前: calculate_volatility
- 引数: prices (list[float]), annualize (bool, 既定 True)
- 処理: 日次リターンの標準偏差を計算する。
annualize=True なら sqrt(252) を掛けて年率換算する。
- 戻り値: float
- 制約: Python 3.12 / 標準ライブラリのみ
- docstring と簡単な使用例を含める

責務・引数・戻り値・制約を分けて書くと、想定どおりの関数が返ります(#7-2「データ分析のためのプロンプト設計」)。

まとめ

  • 関数は def で定義し、return で値を返す
  • デフォルト引数とキーワード引数で呼び出し側の書きやすさが変わる
  • 1 つの関数は 1 つの責務に絞ると再利用とテストがしやすい
  • 引数を直接書き換えない設計を基本にする