複数の戻り値を返す

生田 陸人
LuaGate エンジニア / 現役エンジニア
編集 LuaGate編集部

複数の戻り値を返す とは

関数からタプルで複数の値をまとめて返すパターンを学ぼう。本レッスンでは、複数の戻り値を返す の基本から実際の使いどころまでを整理し、現場で迷わず使える形に落とし込みます。

1 つの関数から複数の値を返す

前のレッスンで触れた divmod のように、Python の関数は 複数の値を一度に返す ことができます。CJava だと「戻り値は 1 つだけ」というルールがあって、複数返したいときはクラスや構造体を作る必要があります。Python ではタプルという形で、ごく自然に複数の値を返せます。

「1 関数 = 1 結果」の壁をひょいと越えられるのが Python の柔軟さ。これを使いこなすと、関数設計が一気に楽になります。

複数戻り値の文法

return の後ろに , で値を並べるだけです。これだけで Python は自動的にタプルにまとめて返してくれます。

Python

def min_max(numbers): return min(numbers), max(numbers) result = min_max([3, 1, 4, 1, 5]) # result は (1, 5) low, high = min_max([3, 1, 4, 1, 5]) # low は 1, high は 5

return a, b と書いた瞬間に、内部的には return (a, b) と同じ意味になります。括弧を省略できる、というだけで、戻り値はあくまでタプルです。

慣れない人向けに、return (a, b) と明示的に書くスタイルもあります。意図がはっきりするので読み手に親切です。

アンパックの基礎

複数戻り値を扱う際のお供が アンパック です。左辺に変数を , で並べることで、タプルやリストの中身を一気に分解できます。

Python

point = (10, 20) x, y = point # x は 10, y は 20 pair = ["apple", 100] name, price = pair # name は "apple", price は 100

左辺の変数の数と、右辺の要素数が合っていないと ValueError になります。a, b, c = (1, 2) のように足りないとエラー、逆に多すぎてもエラーです。要素数の保証されない場合は、* を使ったキャッチオール構文 (first, *rest = lst) も使えますが、これは後の章で詳しく扱います。

動きを追ってみる

def stats(numbers) という関数で、合計と平均を一緒に返す例を考えます。

diagram (will load when visible)

関数の中で 2 つの計算を行い、return total, average のように 1 行でまとめて返します。受け取る側では total, average = stats(nums) のようにアンパックすれば、すぐに 2 つの変数が手に入ります。これが Python らしい関数の使い方です。

よくある間違い

複数戻り値で初学者がはまりやすいパターンは、次の通りです。

  • アンパックの左辺と右辺で要素数が合わず ValueError
  • return a; return b のように 2 行書いてしまい、最初の return で関数が終わる
  • 1 つの変数で受けて、タプルだとは知らずに添字で取ろうとする
  • 順序を勘違いして min, max = max_min(...) のように逆に受ける

特に 2 つ目は致命的です。return は関数の処理を そこで止める ので、return a の後ろに書かれた return b は永遠に実行されません。複数の値を返したいなら、必ず 1 つの return 文に , で並べます。

Python

# NG — b は決して返ってこない def bad(a, b): return a return b # OK def good(a, b): return a, b

return は関数の終わり」という事実は、Python を 10 年書いた人でも時々忘れるくらい大事なポイントです。

名前付きタプルや dataclass という選択肢

戻り値が 2 つ 3 つくらいなら素のタプルで十分ですが、5 つ 10 つと増えてくると「何番目が何だっけ?」と分からなくなります。そんなときに使うのが namedtupledataclass です。

Python

from collections import namedtuple Stats = namedtuple("Stats", ["total", "average", "count"]) def stats(numbers): total = sum(numbers) return Stats(total=total, average=total / len(numbers), count=len(numbers)) r = stats([1, 2, 3]) print(r.total, r.average)

これを使うと、r.total のように名前でアクセスできるので、コードがぐっと読みやすくなります。今回のレッスンでは素のタプル/リストを使いますが、こういう道具もあると頭の片隅に入れておきましょう。

やってみよう

このレッスンの課題は、整数リスト numbers を受け取り、[最小値, 最大値] のリストを返す min_max 関数を実装することです。組み込みの minmax を使えば一発で書けます。

Python

def min_max(numbers): return [min(numbers), max(numbers)]

もしくは、複数戻り値の文法を活かして、内部でタプルで返してリスト化してもよいです。

Python

def min_max(numbers): low, high = min(numbers), max(numbers) return [low, high]

同じ結果でも書き方は何通りもあります。今は読みやすさ優先で書き、慣れたら短い書き方も試していきましょう。

複数戻り値は、Python を書いていると毎日のように出会うパターンです。タプルとアンパックの感覚を、ここでしっかり手に馴染ませておきましょう。

よくある質問

Q. このトピックは Python 以外の言語でも同じ書き方ですか?

A. 考え方は他言語と共通ですが、構文や標準ライブラリは異なります。Python はインデントでブロックを表し、コロン + 改行で構造を作るのが特徴です。他言語に移行する際は基本概念を維持しつつ、構文の差分を意識して書き換えると混乱が少ないです。

Q. 実行してエラーが出た場合の対処は?

A. エラーメッセージの最後の行(TypeError や NameError などの型)から原因と該当行を確認します。Python はトレースバックが下から上に読むと「呼び出し元 → 内部」の順で辿れます。print や IDE のデバッガで途中の変数を確認すると原因が見えてきます。

Q. 次のステップで何を学ぶべきですか?

A. 本レッスンの内容を理解できたら、本文の「やってみよう」を実装し、章末クイズに進むのがおすすめです。さらに自分のミニアプリ(電卓・todo・スコア集計など)に応用するとスキルが定着します。詰まったら本文の H2 セクションに戻って読み返してください。

次のレッスン

次は 実行順序を意識する で、関数からタプルで複数の値をまとめて返すパターンを学ぼう を学びます。

事前確認 — 進む前に次の 3 つができることを確認しましょう。

  1. 複数戻り値 の要点を自分の言葉で説明できる
  2. このレッスンの最小コード (または操作手順) を見ずに書ける
  3. 練習問題やクイズで間違えた箇所を読み直して理解した

理解度チェック (30 秒)

Q. 複数戻り値 とは何か、1 文で説明してください。

この章のポイント

A. 本文の「このレッスンで分かること」または冒頭の説明文を見直し、自分の言葉で要約できれば OK。詰まったら本レッスンの最初の H2 セクションを読み返してみましょう。

関連レッスン

要件

  1. 関数名は min_max、引数はリスト numbers
  2. 戻り値は [最小値, 最大値] のリスト
  3. min と max を活用する

入出力例

test-cases.txt

min_max([3,1,4,1,5])[1,5] min_max([10])[10,10] min_max([-3,-1,-7,-2])[-7,-1] min_max([5,5,5,5])[5,5]

ヒント

main.py
main.py
学習モード

メモ

複数の戻り値を返す

⌘S で保存