コンテンツにスキップ

第4回:関数の引数と戻り値

もし「引数」がなかったら?

例えば、サークルの新歓で全員に同じ挨拶メッセージを送りたいとする。

print('田中さん、新歓へようこそ!3号館201で待ってます')
print('佐藤さん、新歓へようこそ!3号館201で待ってます')
print('鈴木さん、新歓へようこそ!3号館201で待ってます')
print('山田さん、新歓へようこそ!3号館201で待ってます')
# ……50人分書く?

名前のところだけが違って、他は全部同じ。もし会場が「3号館201」から変わったら、50行全部直すことになる。

身近なアプリも全部これ

  • LINEのトーク画面: 「メッセージを画面に表示する関数」が、友達ごとに引数を変えて呼ばれている
  • Amazonの商品一覧: 「商品カードを描く関数」が、商品ごとに引数を変えて呼ばれている
  • YouTubeのおすすめ: 「動画のサムネを表示する関数」が、動画IDごとに引数を変えて呼ばれている

すべて「引数」を使ってテンプレート化している。

引数

引数(ひきすう): 関数を呼び出すときに、関数に渡す値のこと。

def countdown(start):
    print('関数が受け取った値:', start)
    print('カウントダウンをします')
    counter = start
    while counter >= 0:
        print(counter)
        counter -= 1

countdown(3)
countdown(10)
  • def countdown(start):start が、引数を受け取る変数
  • countdown(3)3 が、関数に渡す引数

プレ演習4-1

以下の形で動作する関数 greet を定義してみよう。

greet('田中')
greet('佐藤')
greet('鈴木')

期待される実行結果:

こんにちは、田中さん
こんにちは、佐藤さん
こんにちは、鈴木さん

プレ演習4-2

以下の形で動作する関数 show_double を定義してみよう。

show_double(5)
show_double(100)
show_double(7)

期待される実行結果:

10
200
14

引数が2つある関数

引数はカンマ区切りで複数並べることができる(引数列とよぶ)。

def countdown(start, end):
    print('1つ目の引数で受け取った値:', start)
    print('2つ目の引数で受け取った値:', end)
    print('カウントダウンをします')
    counter = start
    while counter >= end:
        print(counter)
        counter -= 1

countdown(7, 3)

発展:キーワード引数

変数名を指定して呼び出すこともできる。順番を変えてもOK。

countdown(start=7, end=3)
countdown(end=3, start=7)

プレ演習4-3

以下の形で動作する関数 show_sum を定義してみよう。

show_sum(3, 5)
show_sum(10, 20)

期待される実行結果:

8
30

余裕のある人向け:

  • show_sum(3, 5)show_sum(5, 3) で結果は同じ? 違う?
  • 引き算をする関数 show_minus(a, b) を自分で作って、show_minus(10, 3)show_minus(3, 10) を実行してみよう。

もし「戻り値」がなかったら?

例: 3教科の平均点を出して、合格/不合格を判定したい。

def show_average(a, b, c):
    print((a + b + c) / 3)

show_average(80, 70, 90)   # 80.0 と画面に表示される

# でも、「80点が60点以上か」をプログラムで判定したい場合、
# print された数字は、プログラムからは取り出せない

「戻り値」を使うと?

return を使えば、関数の処理結果を呼び出し元に渡せる。

def get_average(a, b, c):
    return (a + b + c) / 3

avg = get_average(80, 70, 90)
if avg >= 60:
    print('合格')
else:
    print('不合格')

戻り値

戻り値: 関数で処理した結果を、呼び出し元に戻す値のこと。

書き方:

def 関数名(引数列):
    # 処理
    return 

例:

def circle_area(r):
    return r * r * 3.14

a = circle_area(2.5)
print('半径2.5の円の面積は', a)

print と return の違い

  • print(x) は画面に表示するだけ。プログラムからは取り出せない。
  • return x は呼び出し元に値を渡す。変数に代入したり、計算に使える。
  • 両方やりたい場合は別々に書く(print してから return するなど)。

プレ演習4-4

以下の形で動作する関数 double_return を定義してみよう。

a = double_return(5)
print('aの中身は: ', a)
ans = double_return(5) + double_return(10)
print('答え = ', ans)

期待される実行結果:

aの中身は:  10
答え =  30

真偽値を戻り値とする関数

True / False を返す関数も作れる。比較式の結果をそのまま返すとすっきり書ける。

# 冗長な書き方
def is_positive(i):
    if i > 0:
        return True
    else:
        return False

# すっきりした書き方
def is_positive(i):
    return i > 0

呼び出し側も同様にすっきりする。

# 冗長
if is_positive(a) == True:
    ...

# すっきり
if is_positive(a):
    ...

複数の値を戻す

複数の値を返したい場合は、タプルを使う。

def get_two_numbers():
    return (2, 3)

a, b = get_two_numbers()
print(a, b)

呼び出し側はアンパック代入(第2回参照)で複数の変数に分けて受け取れる。

発展:デフォルト引数

引数列に 変数名=デフォルト値 と書いておくと、呼び出し時にその引数を省略できる。

def countdown(start, end=0):
    # ... 処理

countdown(10)        # end は 0 として扱われる
countdown(10, 0)     # 明示的に指定してもOK

順番に注意

デフォルト値のある引数は、デフォルト値のない引数より後ろに書く必要がある。

発展:可変長引数

引数の個数を決めずに受け取りたい場合に使う。

*args: タプルで複数の値を受け取る

def func_a(*args):
    for a in args:
        print(a)

func_a(1, 2)
func_a(1, 2, 3, 4)

**kwargs: 辞書でキーと値のペアを受け取る

def func_b(**kwargs):
    for k, v in kwargs.items():
        print(k, v)

func_b(a=1, b=2)
func_b(c=3, d=4, e=5, f=6)

授業内演習

問1

2つの整数の和を計算してその結果を返す関数 my_sum を作成せよ。また、関数 my_sum を用いて、キーボードから入力された2つの整数の和を出力するプログラムを作成せよ。

問2

データ数 n、データ数分の実数データ data、探索値 key を入力して、data の中に key が何個含まれるかを探索して出力するプログラムを作成しなさい。ただし、データ探索には関数を用いること。

基本課題

以下のプログラムは、任意の正整数 n(n ≥ 1)を入力し、1 から n までの総和と 1 から n までの総乗(n の階乗)を求めるものである。関数 total_sum()my_fact() を追加してプログラムを完成させなさい。

n = int(input('nを入力してください ==> '))

print('1 から', n, 'までの総和 = ', total_sum(n))
print('1 から', n, 'までの総乗 = ', my_fact(n))

応用課題

以下のプログラムは、データ数とデータ数分の実数データを入力して、総和、平均値、最大値、最小値、分散、標準偏差を求めて出力するものである。これらを求める関数を追加してプログラムを完成させなさい。

n = int(input('データ数を入力してください ==> '))
data = []

print(n, '個の実数を入力してください')
for i in range(n):
    x = float(input(f'data[{i}] = '))
    data.append(x)

print('総和 = ', my_sum(data, n))
print('平均値 = ', my_ave(data, n))
print('最大値 = ', my_max(data, n))
print('最小値 = ', my_min(data, n))
print('分散 = ', my_var(data, n))
print('標準偏差 = ', my_sqrt(data, n))

標準偏差に使えそうなもの

平方根は math モジュールの sqrt で計算できる。import math のあと、math.sqrt(x)x の平方根が得られる。