ラムダ式について書いていきます。らむだしき、、らむだシキ、、、なんだか難しそうですが、そんな事もありませんので、ご安心を。今回の記事はpythonのユーザ定義関数と簡単なtkinter(てぃきんたー)について理解している方向けになります。
ラムダ式とは無名関数の書き方のこと
プログラミング言語における無名関数(英語: anonymous functionあるいはnameless function)とは、名前付けされずに定義された関数のことである。無名関数を表現するための方法には様々なものがあるが、近年主流となっているのはラムダ式による記法である。無名関数を表現するリテラル式は、関数リテラル (function literal) とも呼ばれる。値がある場合は関数オブジェクトであるものが多い。(wikipediaより引用)
やや難しい表現ですので、詳しく説明していきます
ラムダ式・・・その具体的な書き方とは?
ラムダ式についてざっくり噛み砕いて説明すると、ラムダ式は「名前がない関数」です。pythonの関数を記述する場合、一般的に次の構文に従って関数を定義します。
1 2 |
def 関数名(引数): return 返り値 |
定義した関数はプログラム中に関数名を書くことでいつでも呼び出すことが可能です。それでは、今回注目しているラムダ式の書き方はどうなるかというと
1 |
lambda 引数: 返り値 |
こうなります。この1行がラムダ式です。先ほどの一般的な関数定義と比較してみると「関数名」が存在しないことが確認できると思います。
なぜわざわざラムダ式を使うのか?その理由
なぜラムダ式という書き方があるのでしょうか?簡単なプログラムでラムダ式の魅力を伝えていきたいと思います。まずはtkinterを利用して簡単なウィンドウを作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import tkinter root = tkinter.Tk() root.option_add("*font", ["Mylodon-Light", 22]) root.minsize(400, 400) #キャンバス作成 canvas = tkinter.Canvas(bg="#aaaaaa", width=400, height=400) canvas.place(x=-3, y=-3) #入力ボックス作成 entry = tkinter.Entry(width=10, bg="white", justify='center') entry.place(x=80, y=100) #ボタン作成 button1 = tkinter.Button(text="1", height="2", width="2") button1.place(x=180, y=280) #ボタン押した時の処理 def ButtonPush(): entry.delete(0, tkinter.END) entry.insert(tkinter.END, "りんご") #ボタン処理の割り当て button1["command"] = ButtonPush root.mainloop() |
実行結果
ボタンを押すと「りんご」という文字が表示されます。tkinterではボタンに処理を割り当てる場合、関数を指定する必要があります。上のプログラムの場合、「りんご」という文字を表示するプログラムをButtonPushという関数として作成し、ボタンに割り当てました。
1 2 3 4 5 6 7 |
#ボタン押した時の処理 def ButtonPush(): entry.delete(0, tkinter.END) entry.insert(tkinter.END, "りんご") #ボタン処理の割り当て button1["command"] = ButtonPush |
ここまでは問題ないかと思います。問題は次のケースです。
上の図のような簡単な電卓をtkinterで作成するとします。電卓なので、数字のボタンをクリックすると数字が表示されるようにする必要があります。今回の例では、ボタンの数が増えていますが、「文字を表示する」という処理内容は先ほどの例と変わらないためボタンの数だけ関数を増やし、それぞれのボタンに処理を割り当てれば問題なく作成できそうです。
ラムダ式を使わないとどうなるか?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# 7ボタン押した時の処理 def ButtonPush7(): entry.insert(tkinter.END, "7") button7 = tkinter.Button(text="7", height="2", width="2") button7.place(x=50, y=110) button7["command"] = ButtonPush7 # 8ボタン押した時の処理 def ButtonPush8(): entry.insert(tkinter.END, "8") button8 = tkinter.Button(text="8", height="2", width="2") button8.place(x=100, y=110) button8["command"] = ButtonPush8 # 9ボタン押した時の処理 def ButtonPush9(): entry.insert(tkinter.END, "9") button9 = tkinter.Button(text="9", height="2", width="2") button9.place(x=150, y=110) button9["command"] = ButtonPush9 |
・・・7,8,9のボタンだけなのにめっちゃ行数多い(笑)入力欄に文字を入れるという1つの処理のために同じ内容の関数を何度も定義するのはあまり効率がよくありませんよね。ここでラムダ式の登場です。その前にここでラムダ式の書き方のおさらいです。ラムダ式は次のように書くことが可能です。
1 |
lambda 引数: 返り値 |
ラムダ式を使用すると、電卓のボタンは次のように、関数を定義することなくボタンに処理を割り当てることが可能になります。
ラムダ式で効率的にコーディング
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# 7ボタン押した時の処理 button7 = tkinter.Button(text="7", height="2", width="2") button7.place(x=50, y=110) button7["command"] = lambda: entry.insert(tkinter.END, button7["text"]) //ラムダ式 # 8ボタン押した時の処理 button8 = tkinter.Button(text="8", height="2", width="2") button8.place(x=100, y=110) button8["command"] = lambda: entry.insert(tkinter.END, button8["text"]) //ラムダ式 # 9ボタン押した時の処理 button9 = tkinter.Button(text="9", height="2", width="2") button9.place(x=150, y=110) button9["command"] = lambda: entry.insert(tkinter.END, button9["text"]) //ラムダ式 |
名前がない関数だからこそ直接処理内容を記述することが可能となり、スッキリしたコードになりました。プログラミングを習い始めの方に多いケースとして、1つの書き方を覚えると、その書き方に固執するケースがありますが、1つの方法だけでなくもっと良い書き方はないかな?と学習を深めていくことで、レベルアップに繋がっていくと思います。プログラムを書きながら「なんか無駄に書いてるきがするな」と感じたら間違いなくもっと効率の良い書き方が存在するはずなので、自分自身のレベルアップのためにも色々と探求してみてください。
・・・ということで電卓の数字ボタンの入力のもう1つの解決方法です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# 関数定期 def ButtonPush(event): entry.insert(tkinter.END, event.widget["text"]) # 7ボタン押した時の処理 button = tkinter.Button(text="7", height="2", width="2") button.place(x=50, y=110) button.bind("<Button-1>", ButtonPush) # 8ボタン押した時の処理 button = tkinter.Button(text="8", height="2", width="2") button.place(x=100, y=110) button.bind("<Button-1>", ButtonPush) # 9ボタン押した時の処理 button = tkinter.Button(text="9", height="2", width="2") button.place(x=150, y=110) button.bind("<Button-1>", ButtonPush) |
この書き方でも問題なく入力欄に数字を表示することが可能です。ボタンに処理を割り当てる際に[“command”]ではなくbindを利用することで押されたボタンの情報を引数にして関数を実行することができるようになります。これによりButtonPush関数を各ボタンで共有することが可能になり、同じ関数を何度も記述する必要がなくなりました。他にも色々な解決方法があると思いますのでぜひ色々試行錯誤して楽しんでみてください。それでは、また。