複数の戻り値
このレッスンで作るもの — 1 つの関数から 2 つの答えを返す方法を覚え、合計と平均を同時に返す
total_and_averageを作ります。
複数の戻り値
支出の一覧を見るとき、知りたいのはたいてい 1 つではありません。合計も平均も両方ほしい、というのが普通です。
Python の関数は、return のうしろにカンマで値を並べるだけで、複数の値をまとめて返せます。
def total_and_average(prices):
total = sum(prices)
return total, total / len(prices)return a, b と書くと、Python は (a, b) という タプル を作って返します。タプルは「変更できない並び」で、リストの親戚のようなものです。
この内容が第 6 章にあるのは偶然ではありません。複数の値を返すには、まず関数と戻り値そのものが分かっている必要があるからです。順番として、ここが最初に置ける場所です。
受け取り方はアンパック
返ってきた 2 つの値は、左辺に変数を 2 つ並べて受け取れます。これを アンパック と呼びます。
total, average = total_and_average([120, 80, 300])total に 500、average に 166.666... が入ります。左辺の数と右辺の数が合っていないと ValueError になります。1 つの変数で受ければ、並びがまるごと 1 つの値として入ります。
アンパックはリストにも同じように効きます。[500, 166.7] を返す関数でも、total, average = ... で分けて受け取れます。この学習環境の判定はリスト形式で行うため、演習ではタプルではなく リストで返す ことにします。考え方も受け取り方も、どちらでも変わりません。
平均は割り切れない
500 / 3 は 166.66666666666666 です。このままでは画面に出しても読みにくいので、round で小数第 1 位に丸めます。
average = round(total / len(prices), 2)round(値, 桁数) の 2 つ目の引数が、小数点以下を何桁残すかです。round(166.66666666666666, 1) は 166.7 になります。桁数を省略すると整数に丸められます。
sum はリストの合計を、len は要素の個数を返す組み込み関数です。第 5 章では for で 1 つずつ足しましたが、合計を出すだけなら sum で十分です。
空のときを先に決める
支出が 1 件もないとき、len(prices) は 0 です。total / 0 は ZeroDivisionError で止まります。
if len(prices) == 0:
return [0, 0]関数の入口でこう書いておけば、あとの計算は安心して書けます。「危ない入力を先に返してしまう」この形は、実務でもよく使う書き方です。
エラーで止まるプログラムより、決めておいた答えを返すプログラムの方が使えます。0 件のときにどうするかは、必ず自分で決めます。
動きを追ってみる
total_and_average([120, 80, 300]) の流れは下記のとおりです。
- 件数は
3で0ではないので、そのまま先へ進む sum([120, 80, 300])でtotalが500になる500 / 3は166.66666666666666、round(..., 1)で166.7になる[500, 166.7]が返る
よくある間違い
returnを 2 行書く —return totalの次の行にreturn averageと書いても、2 行目には決して届きません。returnは関数を終わらせるので、1 つのreturnにカンマで並べます。- 受け取る変数の数が合わない —
total, average, count = total_and_average(prices)はValueErrorです。not enough values to unpackと出ます。 - 空のリストを忘れる — 0 件で
ZeroDivisionErrorになります。テストには必ず空の場合を入れて確かめます。
やってみよう
関数 total_and_average(prices) を実装してください。金額のリスト prices を受け取り、[合計, 平均] というリストを return します。
平均は round で小数第 1 位まで丸めます。prices が空のリストのときは [0, 0] を返します。手元では total, average = total_and_average([120, 80, 300]) と書いて受け取り、print(total) と print(average) の両方を見てみてください。
要件
- 関数名は total_and_average で、引数はリスト prices の 1 つ
- 戻り値は [合計, 平均] のリスト
- 平均は round で小数第 1 位まで丸める
- prices が空のリストのときは [0, 0] を返す
入出力例
total_and_average([120,80,300]) → [500,166.7]
total_and_average([100,200]) → [300,150]
total_and_average([]) → [0,0]
total_and_average([350]) → [350,350]
total_and_average([0,0,0]) → [0,0]