Lesson 3

関数

Lesson 3 Chapter 1
関数を定義する

プログラムを作成する過程では、同じ処理が何度も必要になる場面が出てきます。そのような時に、自ら同じプログラムを何度も記述するのは手間であると容易に想像できるはずです。そこで、特定の処理を部品として定義することで、繰り返し使用することが可能になります。
Lesson2までで、Pythonの基礎文法を学んできましたが、それを用いることで自ら部品を作成することが可能です。Lesson3では、基礎文法を使用しながら特定の処理を実行する部品である「関数」を作成していきます。

関数とは

関数とは、与えられた値をインプット情報として特定の処理を実行する部品です。この部品となる関数を定義することで、頻繁に使用する処理や複雑な処理を何度もコーディングすることなく、定義した関数を呼び出すことでいつでも簡単に同じ処理を実行させることが可能になります。

今までのレッスンで利用した「print」も関数の一つです。画面に出力するプログラムを何度も記述することなく、print関数の引数に出力したい値を設定するだけで、簡単に画面出力が可能となっていたはずです。

print関数など、Pythonが最初から提供してくれているものを「組み込み関数」といいます。組み込み関数とは別に、ユーザ自身が関数を作成することも可能です。これを「ユーザ定義関数」といい、Lesson3ではこのユーザ定義関数を解説していきます。

関数を定義する

関数を定義するには、「def 関数名」として定義します。このdefは、定義することを意味するdefinitionであると覚えてください。
早速、文字出力を実行する関数を記述してみましょう。
以下のサンプルコードは、関数「testFunction」を定義しています。定義した関数を呼び出すためには、関数名「testFunction」の後に"()"を付けて呼び出します。"()"内に出力したい文字列を指定するために、変数に文字列を設定するコード(sampleArgument = 'Hello')もあわせて記述します。

def1_test.py
def testFunction(x):
    print(x)

sampleArgument = 'Hello'
testFunction(sampleArgument)

出力結果

Hello World

関数内の出力処理が実行されたことが確認できたはずです。

returnを使って戻り値を返す

次に、「return文」を使用して関数から戻り値を取得します。先程は、呼び出した関数内で出力処理を行いましたが、今回は関数の呼び出し時に指定した文字列を加工して、その結果を戻す関数を定義します。関数は値を戻すだけなので、戻って来た値を出力する処理が必要になります。

def2_test.py
def char_join_Function(x):
    sentence = x + ' ' + 'World'
    return sentence

sampleArgument = 'Hello'
print(char_join_Function(sampleArgument))

出力結果

Hello World

return文に変数sentenceを指定することで、関数からの戻り値は、変数sentenceになります。関数側では呼び出し時に指定された変数sampleArgument(='Hello')の値に、空白と文字列"World"を付与した"Hello World"を変数sentenceに格納して、return文で戻します。このため、最終的にprint関数で出力された文字列はHello World"になりました。

引数の使い方

関数名の後に"()"を付けて関数を呼び出しましたが、この"()"の中の値を色々と変更して、受け取った値に応じて処理を変える関数の動作を確認しましょう。

def3_test.py
def judgementFunction(x):
    if x > 50:
        return 'OK'
    elif x == 0:
        return 'Zero'
    else:
        return 'NG'

points= 70
print(judgementFunction(points))

出力結果

OK

変数pointsに数値:70を指定して関数judgementFunctionを呼び出すことで、関数の引数xにも数値:70が渡されます。関数は渡された引数を元にif文を処理して、結果をreturn文で戻り値として返しています。
変数pointsを数値:30に書き替えて実行してみましょう。

def3_test.py
def judgementFunction(x):
    if x > 50:
        return 'OK'
    elif x == 0:
        return 'Zero'
    else:
        return 'NG'

points= 30
print(judgementFunction(points))

出力結果

NG

return文の戻り値が"NG"となり、出力結果が変わっています。
このように、利用頻度の多い処理は関数を定義しておき、引数のみを変えることで、必要に応じた結果を得ることが可能になります。

引数の複数指定方法

引数は複数設定が可能です。複数引数の指定方法と、その際の動作について確認しましょう。以下は、3つの値の合計を出力する関数です。関数sumFunctionを呼び出す際に、引数にも3つの数値を指定します。

def4_test.py
def sumFunction(x, y, z):
    result = x + y + z
    return result

arg1 = 1 #第一引数指定
arg2 = 2 #第二引数指定
arg3 = 3 #第三引数指定

print(sumFunction(arg1, arg2, arg3))

出力結果

6

コメントアウトについて

Pythonでは、"#"はコメントアウトとして扱われます。
コメントアウトとは、"#"以降に記述したコードが処理から除外されます。一時的に処理を行わず後で戻したい時や、処理の内容を記述する際などに利用されます。
コンピュータには見えず、人間のみが見えるようになるといったイメージで捉えてください。

呼び出す際の引数の数値を変えて実行してみましょう。

def4_test.py
def sumFunction(x, y, z):
    result = x + y + z
    return result

arg1 = 5 #第一引数指定
arg2 = 20 #第二引数指定
arg3 = 7 #第三引数指定

print(sumFunction(arg1, arg2, arg3))

出力結果

32

このように、関数を呼び出す際の引数へは複数設定が可能です。

関数の型について

文字列や数値と同様に、関数にも型があります。関数の型は「function型」です。type関数を使用して確認できます。

type_def_test.py
def testFunction(x):
    print(x)

print(type(testFunction))

出力結果

<class 'function'>

Lesson 3 Chapter 2
デフォルト引数

関数の処理内容によっては、引数無しで関数を呼び出すとエラーが発生することもあります。そこで、関数側に引数無しで呼び出された際の設定が必要になります。このChapter2では、その設定となる「デフォルト引数」について解説します。

デフォルト引数とは

関数の呼び出し時に引数を設定しない場合において使用されるのが、デフォルト引数です。デフォルト引数は初期値となるので、デフォルト引数を設定していない関数に対して、引数無しで呼び出した場合はエラーになります。

デフォルト引数の使い方

デフォルト引数は、引数無しで関数が呼び出された場合の初期値のため、関数内に記述します。最初にデフォルト引数が無い関数の動作を、以下のコードで確認します。

default_test.py
def addressinfo_Function(info_1, info_2, info_3):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(name, postal_code, address)

出力結果

名前 = 山田
郵便番号 = 151-0053
住所 = 渋谷区代々木

次に、引数無しで関数を呼び出します。

def addressinfo_Function(info_1, info_2, info_3):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function()

出力結果

TypeError: addressinfo_Function() missing 3 required positional arguments: 'info_1', 'info_2', and 'info_3'

「TypeError」が出力され、エラーになりました。そこで、引数なしで関数を呼び出した場合でもエラーにならないよう、デフォルト引数を指定します。

default_test.py
def addressinfo_Function(info_1 = '名前登録なし', info_2 = '郵便番号登録なし', info_3 = '住所登録なし'):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function()

出力結果

名前 = 名前登録なし
郵便番号 = 郵便番号登録なし
住所 = 住所登録なし

引数なしで関数を呼び出した場合でも、デフォルト引数が出力されエラーになりません。引数の一部を省略した場合でも、デフォルト引数は有効です。省略した際の動作をいくつか確認してみましょう。

第一引数のみ指定します。

def addressinfo_Function(info_1 = '名前登録なし', info_2 = '郵便番号登録なし', info_3 = '住所登録なし'):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(name)

出力結果

名前 = 山田
郵便番号 = 郵便番号登録なし
住所 = 住所登録なし

第一引数と第二引数を指定します。

def addressinfo_Function(info_1 = '名前登録なし', info_2 = '郵便番号登録なし', info_3 = '住所登録なし'):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(name,postal_code)

出力結果

名前 = 山田
郵便番号 = 151-0053
住所 = 住所登録なし

デフォルト引数の注意点

デフォルト引数には、リストの設定も可能です。しかし、Pythonではリストをデフォルト引数に指定することは推奨されていません。リストのコピーは参照渡しであることを、Lesson2のChapter5で解説しました。この参照渡しであることが、推奨されない理由です。実際にデフォルト引数にリストを指定して、その動作を確認しましょう。

以下のサンプルコードのように、リストに対して値を追加(append)したリストを戻り値とする関数を作成します。関数にはデフォル引数として、空のリスト(lst=[])の作成を記述します。

list_test.py
def listtest_Function(x, lst=[]):
    lst.append(x)
    return lst

次に、第一引数に60、第二引数にリスト[1,2,3,4,5]を指定して関数を呼び出し、戻り値の結果を出力するprint関数も追加して実行してみましょう。

list_test.py
def listtest_Function(x, lst=[]):
    lst.append(x)
    return lst

append_value = 60
samplelst = [1,2,3,4,5]

print(listtest_Function(append_value, samplelst))

出力結果

[1, 2, 3, 4, 5, 60]

samplelst = [1,2,3,4,5]のリストに対して、60が追加されたリストが戻り値として返されたことが確認できました。

では、関数を呼び出す際の引数を一つのみにして、デフォルト引数(lst=[])が有効となった際の動作を確認しましょう。以下のようにコードを修正して実行してください。

list_test.py
def listtest_Function(x, lst=[]):
    lst.append(x)
    return lst

append_value = 60

print(listtest_Function(60))

出力結果

[60]

関数呼び出し時の引数は、第一引数の60のみであり、第二引数にリストを指定していません。このため、デフォルト引数(lst=[])によって空のリストが作成され、そこに60が追加された結果が戻り値として返却されました。

もう一つリストを作成するために、関数を呼び出すコードを追加して実行します。

list_test.py
def listtest_Function(x, lst=[]):
    lst.append(x)
    return lst

append_value1 = 60
append_value2 = 70

print(listtest_Function(append_value1))
print(listtest_Function(append_value2))

出力結果

[60]
[60, 70]

[60]と[70]のそれぞれのリストではなく、最初に作成したリストに70が追加された結果となりました。これは、最初にlisttest_Function(append_value1)で関数を呼び出した際、デフォルト引数(lst=[])によって空のリスト"lst"が作成されます。
次に、listtest_Function(append_value2)で関数を呼び出す際も第二引数の指定がないため、デフォルト引数によって空のリスト"lst"を作成しようとしますが、既に作成済であるため、そのメモリアドレスを参照して追加処理が実行されます。結果、[60]と[70]のリストではなく、[60, 70]というリストが作成されたわけです。

以上のように、デフォルト引数でリストを使用するとバグに繋がる動作となる懸念が出てきます。デフォルト引数にリストを使用するのではなく、関数の処理内でリストを作成するプログラムにすることで、この懸念が解消できます。

リストを作成する際は、以下のように引数が指定されなかった場合の条件分岐処理を関数内に記述するようにしましょう。

list_test.py
def listtest_Function(x, lst=None):
    if lst is None:
        lst = []
    lst.append(x)
    return lst


append_value1 = 60
append_value2 = 70

print(listtest_Function(append_value1))
print(listtest_Function(append_value2))

出力結果

[60]
[70]

「None」について

Noneとは、"何も存在しない"ことを表す定数です。つまり、値が存在しないことを表します。他の言語ではNullが用いられますが、PythonではNoneとなるので覚えておきましょう。

Lesson 3 Chapter 3
キーワード引数

関数を呼び出す際の引数の指定については、左から順に指定する方法を学んできましたが、Chapter3では別の指定方法を解説します。引数の指定方法は一つではないということを覚えていきましょう。

キーワード引数とは

これまで関数を呼び出す際の引数は、第一引数・第二引数といったように、呼び出し時に記述した順番で関数に値が渡されていました。しかし、順番で指定するのではなく、引数に名称を付与して「引数名=値」といったように、どの引数名に何を設定するのかを明示的に指定することが可能です。この方法を"キーワード引数"といいます。

キーワード引数の使い方

関数を呼び出す際に、引数だけを記述するのではなく、関数内で定義されている引数名を合わせて指定する方法をキーワード引数といいます。 以下のサンプルコードでは、関数側でinfo_1・info_2・info_3の3つの引数名が定義されています。これまで関数の呼び出しは、3つの引数順に合うように「addressinfo_Function(name, postal_code, address)」のような指定方法でコードを記述していました。

test.py
def addressinfo_Function(info_1, info_2, info_3):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(name, postal_code, address)

出力結果

名前 =  山田
郵便番号 =  151-0053
住所 =  渋谷区代々木

キーワー引数では、以下のように関数側で定義されている引数名を指定して、関数を呼び出します。

addressinfo_Function(info_1 = name, info_2 = postal_code, info_3 = address)

キーワード引数に誤りがなければ、引数の指定順は問われません。関数で定義された引数順とは違った順序で関数を呼び出してみます。

test.py
def addressinfo_Function(info_1, info_2, info_3):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(info_2 = postal_code, info_1 = name, info_3 = address)

出力結果

名前 = 山田
郵便番号 = 151-0053
住所 = 渋谷区代々木

関数呼び出し時の引数でinfo_2を先に指定しましたが、キーワード引数として指定しているため問題なく関数内で処理され、先程までと同じ結果が出力されました。
ただし、以下のように関数内で同一引数と判断されてしまうような指定方法はエラーになります。

test.py
def addressinfo_Function(info_1, info_2, info_3):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(info_2 = postal_code, name, info_3 = address)

出力結果

SyntaxError: positional argument follows keyword argument

第二引数にキーワード無しで変数name(=山田)を設定しましたが、キーワード引数で"151-0053"も指定しました。関数側では、info_2に設定すべき値が変数nameであるべきか、"151-0053"であるべきかを判断できないため「SyntaxError」が出力されエラーとなります。

同一引数と判断されない以下のような指定方法は、エラーにはなりません。

test.py
def addressinfo_Function(info_1, info_2, info_3):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(name, info_2 = postal_code, info_3 = address)

出力結果

名前 =  山田
郵便番号 =  151-0053
住所 =  渋谷区代々木

Lesson 3 Chapter 4
任意引数リスト

関数で受け取る引数は、設定次第で多くの引数を受け取り、処理することが可能です。では、受け取る引数が多い処理をコーディングする際は、関数側の引数設定も合わせて書き加えていかなければならないのでしょうか?それは、面倒な作業になりますよね。そこで、受け取る引数が増えた場合でも、今回解説する「任意引数リスト」を用いてコーディングすることで、関数側の設定を簡易にすることが可能です。

任意引数リストとは

任意引数リストとは、可変長引数を意味します。これまで関数を定義する際には、関数側で受け取る引数を指定することで引数は固定数でしたが、任意引数リストを使用することで可変長になります。可変長となることで、関数側での細かな引数指定を不要にすることが可能です。

任意引数リストの使い方

まずは、任意引数リストを使用しない、今まで通りの引数を固定数とした関数を定義します。

test.py
def addressinfo_Function(info_1, info_2, info_3):
    print(info_1)
    print(info_2)
    print(info_3)

name = '山田'
postal_code = '151-0053'
address = '渋谷区代々木'

addressinfo_Function(name, postal_code, address)

出力結果

山田
151-0053
渋谷区代々木

次に、出力情報を増やすために、関数側の引数定義を追加してみましょう。

def addressinfo_Function(info_1, info_2, info_3, info_4, info_5, info_6):
    print(info_1)
    print(info_2)
    print(info_3)
    print(info_4)
    print(info_5)
    print(info_6)

name = '山田'
postal_code = '151-0053'
address1 = '渋谷区代々木'
address2 = '2-3-1'
address3 = 'マンション代々木'
TEL = '03-1234-5678'

addressinfo_Function(name, postal_code, address1, address2, address3, TEL)

出力結果

山田
151-0053
渋谷区代々木
2-3-1
マンション代々木
03-1234-5678

固定数の場合は受け取る引数を増やした分、関数側で定義する引数も増やしていかなければなりません。これではコードが煩雑になりやすく、手間でもあります。このような場合に任意引数リストを使用します。

任意引数リストは、「*args」と定義することで使用可能です。「*args」を使用してコードを修正しましょう。

test.py
def addressinfo_Function(*args):
    print(args)

name = '山田'
postal_code = '151-0053'
address1 = '渋谷区代々木'
address2 = '2-3-1'
address3 = 'マンション代々木'
TEL = '03-1234-5678'

addressinfo_Function(name, postal_code, address1, address2, address3, TEL)

出力結果

('山田', '151-0053', '渋谷区代々木', '2-3-1', 'マンション代々木', '03-1234-5678')

関数側で「*args」を定義することで、受け取る引数の数は任意となり、幾つでも受け取ることが可能になりました。「*args」のデータ型はタプルという型になります。type関数を使って「*args」の型を確認してみしょう。

test.py
def addressinfo_Function(*args):
    print(type(args))

addressinfo_Function()

出力結果

<class 'tuple'>

出力結果から、タプル型であることが確認できます。タプルについては、Lesson4で解説していきますので、このレッスンでは「*args」はタプル型であるということのみ覚えておいてください。

タプル型に変換された値をfor文を使用し、一行ずつ出力するコードに修正しましょう。

test.py
def addressinfo_Function(*args):
    for x in args:
        print(x)

name = '山田'
postal_code = '151-0053'
address1 = '渋谷区代々木'
address2 = '2-3-1'
address3 = 'マンション代々木'
TEL = '03-1234-5678'

addressinfo_Function(name, postal_code, address1, address2, address3, TEL)

出力結果

山田
151-0053
渋谷区代々木
2-3-1
マンション代々木
03-1234-5678

引数としての使い方

関数側で「*args」を一つの引数として使用することも可能です。「*args」を第二引数として使用してみましょう。

test.py
def addressinfo_Function(name_info,*args):
    print(name_info)
    for x in args:
        print(x)

name = '山田'
postal_code = '151-0053'
address1 = '渋谷区代々木'
address2 = '2-3-1'
address3 = 'マンション代々木'
TEL = '03-1234-5678'

addressinfo_Function(name, postal_code, address1, address2, address3, TEL)

出力結果

山田
151-0053
渋谷区代々木
2-3-1
マンション代々木
03-1234-5678

第一引数に指定した変数name(=山田)のみが最初のprint関数で処理され、それ以外は、「*args」に纏められfor文で処理されました。

Lesson 3 Chapter 5
引数リストのアンパック

Lesson2のChapter5でリストを定義した際に、リストに定義した一つひとつの値は、要素と呼ばれると解説しました。この要素に対して、インデックスを使用した要素の取り出し(スライス)を合わせて学びましたが、それとは別でアンパックという方法がリストに対して利用可能です。アンパックを利用することで、要素を変数に代入することができます。スライスは取り出しでしたが、アンパックは展開(分解)になります。この言葉の違いを意識することで、このレッスンの理解が深まると思います。

アンパックとは

アンパックとは、複数の要素を展開(分解)して、変数に一つずつ代入することを意味します。

引数リストのアンパック

アンパックを使用して、リスト内の要素を一つひとつの変数に展開してみましょう。

今回は「.py」ファイルを作成しなくとも、Windowsの場合はコマンドプロンプト、macOSの場合はターミナルを利用して確認が可能です。

まずはリストを作成します。

>>> lst = [1,2,3,4,5]

次に、作成したリストをアンパックします。

>>> unpack_1,unpack_2,unpack_3,unpack_4,unpack_5 = lst

アンパックされた結果をprint関数で出力して確認します。

出力結果

>>> print(unpack_1)
1
>>> print(unpack_2)
2
>>> print(unpack_3)
3
>>> print(unpack_4)
4
>>> print(unpack_5)
5

リストの1〜5までの要素が、変数unpack_1〜5に展開されました。これが、アンパックです。

アスタリスク(*)を使ったアンパック

アンパックを行う場合は、リストの要素数と、展開する変数の数が一致している必要があります。不一致の場合は、以下のようにアンパックできずエラーとなります。

>>> lst = [1,2,3,4,5]
>>> unpack_1,unpack_2,unpack_3 = lst

出力結果

ValueError: too many values to unpack (expected 3)

「ValueError」が出力され、アンパックがエラーとなりました。このような場合は、アスタリスク(*)を使用することでアンパックが可能になります。

>>> lst = [1,2,3,4,5]
>>> unpack_1,unpack_2,*unpack = lst

出力結果

>>> print(unpack_1)
1
>>> print(unpack_2)
2
>>> print(unpack)
[3, 4, 5]

アスタリスク(*)を使用することで、正常にアンパックが行えました。出力結果で確認できるとおり、print(unpack)の出力結果は括弧([])で囲まれています。アスタリスクを使用した場合には、リストとしてアンパックされます。

アスタリスクは、先頭や真ん中にも指定することが可能です。

>>> lst = [1,2,3,4,5]
>>> *unpack,unpack_1,unpack_2 = lst

出力結果

>>> print(unpack)
[1, 2, 3]
>>> print(unpack_1)
4
>>> print(unpack_2)
5

アスタリスク(*)を真ん中に指定します。

>>> lst = [1,2,3,4,5]
>>> unpack_1,*unpack,unpack_2 = lst

出力結果

>>> print(unpack_1)
1
>>> print(unpack)
[2, 3, 4]
>>> print(unpack_2)
5

ネストされたリストのアンパック方法

リストがネスト(入れ子)された場合でも、アンパックは可能です。

>>> lst = [[1,2,3,4,5],[6,7,8,9,10]]
>>> unpack_1,unpack_2 = lst

出力結果

>>> print(unpack_1)
[1, 2, 3, 4, 5]
>>> print(unpack_2)
[6, 7, 8, 9, 10]

ネストされた中身をアンパックすることも可能です。

>>> lst = [[1,2,3,4,5],[6,7,8,9,10]]
>>> (unpack_1,unpack_2,unpack_3,unpack_3,unpack_5),unpack = lst

出力結果

>>> print(unpack_1)
1
>>> print(unpack_2)
2
>>> print(unpack_3)
3
>>> print(unpack_4)
4
>>> print(unpack_5)
5
>>> print(unpack)
[6, 7, 8, 9, 10]

最初のリストの要素1〜5は変数unpack_1〜5に展開され、2つ目のリストの要素6〜10はリストのまま変数unpackに展開されました。

アンパックを使用した関数の呼び出し

関数を呼び出す際にも、アンパックを使用することが可能です。リストを関数呼び出し時の引数に設定して、アンパックを合わせて使用してみましょう。「.py」ファイルに以下のコードを記述して実行してください。

unpk_test.py
def addressinfo_Function(info_1, info_2, info_3):
    print('名前 =', info_1)
    print('郵便番号 =', info_2)
    print('住所 =', info_3)

input_lst = ['山田', '151-0053', '渋谷区代々木']

addressinfo_Function(*input_lst)

出力結果

名前 = 山田
郵便番号 = 151-0053
住所 = 渋谷区代々木

関数呼び出し時の引数として指定したリストが、関数の引数に展開されて処理が実行されました。

Lesson 3 Chapter 6
ラムダ式

関数を定義する際は、Chapter1でdef文を使用して定義すると学びましたが、このdef文を使用せずに関数の利用を可能とする方法をこのChapterでは解説します。

ラムダ式とは

def文を使用せずに関数の利用を可能とする方法を「ラムダ式」といいます。def文を使用しないということは、関数名を持たないことを意味し、ラムダ式は無名関数とも呼ばれます。ラムダ式を用いれば、簡易な処理の場合にわざわざ関数の定義をすることなく、コーディングが可能となります。

ラムダ式の使い方

def文のみを使用した処理と、ラムダ式を用いた処理それぞれのプログラムを比較しながら違いについて理解を深めましょう。まずは今まで学習してきたdef文のみを使って、リスト内の小文字を大文字に変換して出力する処理を記述します。

def_test.py
def word_chg(lower_word,func_chg):
    for x in lower_word:
        print(func_chg(x))

def sample(word):
    return word.upper()

lst = ['morning','afternoon','evening','night']

word_chg(lst,sample)

出力結果

MORNING
AFTERNOON
EVENING
NIGHT

word_chg関数を呼び出す際の第二引数にsample関数を指定することで、word_chg関数の第二引数func_chgにもsample関数が指定されます。これにより、word_chg関数のprint処理時にsample関数が呼び出され、大文字への変換処理が実行されています。最後にreturn文の返り値をword_chg関数が受け取り、大文字に変換された文字出力を実現しています。

次に、同じ処理にラムダ式を使用したコードを別ファイルに記述します。

ラムダ式の構文は「lambda 引数: 処理」です。「lambda 引数1,引数2,引数3: 処理」といったように、カンマ(,)区切りで複数の引数を指定することも可能です。

lambda1_test.py
def word_chg(lower_word,func_chg):
    for x in lower_word:
        print(func_chg(x))

lst = ['morning','afternoon','evening','night']

word_chg(lst,lambda word: word.upper())

出力結果

MORNING
AFTERNOON
EVENING
NIGHT

ラムダ式を使用することで、sample関数が不要となり、コードもシンプルにすることができました。sample関数が担っていた大文字への変換処理を、ラムダ式の一文で実現しています。

このように簡単な関数をわざわざdef文を使い定義することなく、ラムダ式で置き換えることが可能です。

ラムダ式と高階関数

ラムダ式は、高階関数と組み合わせて活用されます。高階関数とは、「引数に関数を取る関数」を意味します。代表的な高階関数にmap関数が挙げられます。

map関数とラムダ式を合わせた記述方法を解説します。コードに少しずつ処理を追記する形で解説していくので、追記する内容を理解しながら進めてください。

まずは、小文字の単語リストを作成します。

lambda2_test.py
lst = ['morning','afternoon','evening','night']

小文字から先頭のみを大文字に変換するラムダ式を追記します。

lambda2_test.py
lst = ['morning','afternoon','evening','night']

lambda word: word.capitalize()

次に、map関数を追記します。map関数は、配列のすべての要素に対して、関数を適用させることが可能になります。構文は「map(関数,リストなどのオブジェクト)」なので、第一引数(関数)にラムダ式、第二引数(リスト)にリストlstを指定します。変数word_chgに、map関数の結果を代入しprint関数で出力してみましょう。

lambda2_test.py
lst = ['morning','afternoon','evening','night']

word_chg = map(lambda word: word.capitalize(),lst)
print(word_chg)

出力結果

<map object at 0x10eaaf820>

map関数の結果のままでは、出力結果のとおり大文字に変換後のリストになってはいません。最後にリストへ変換するための、list関数を追記します。全ての記述が完了後に実行してみましょう。

lambda2_test.py
lst = ['morning','afternoon','evening','night']

word_chg =list(map(lambda word: word.capitalize(),lst))
print(word_chg)

出力結果

['Morning', 'Afternoon', 'Evening', 'Night']

このように、「引数に関数を取る関数」である高階関数とラムダ式を組み合わせて使用することが可能です。