Python

【Python初心者】 関数のlamda式、ジェネレーター、デコレーターを理解しよう。

こんにちは(@t_kun_kamakiri)(‘◇’)ゞ

この記事ではPythonの「関数」について解説します。
関数の基本的な内容は前回の記事で解説をしております。

前回の記事はこちら

 

今回は、前回学んだ関数の続きをやります。

この記事で学ぶこと
  1. ラムダ式:小さな処理を書く
  2. ジェネレーター:1つずつ取り出す処理(yield関数)
  3. デコレーター:関数に機能を追加・変更

Pytonの関数は以下の2通りを覚えておきましょう。

「def 関数名()」の基本的な書き方

「lambda パラメータ1, パラメータ2 : 処理」の書き方

今回は「lambda 式」を使った関数設定の方法について解説をします。
その他、ジェネレーター・デコレーターという覚えておくと便利な方法についても紹介しておきましょう!
使用環境を示しておかないと混乱しそうなのでちゃんと書いておきます(^^)/

【Pythonの使用環境について】
Anaconda
Google Colaboratory
当ブログはこれをメインに使った計算結果です。

関連記事

 

☟書籍も紹介しておきます。
こちらの本がPython初心者が挫折することなく勉強できる本です。
(本記事のようのPython使用環境と異なりますが、とてもわかりやすいので全く問題ありません)

スポンサーリンク

ラムダ式

わざわざ関数を作るまでもないときに、無名関数(関数に名前を付けない)方法で、関数を設定することができます。

それがラムダ式です。

書き方は以下です。

実際に、defを使って関数を設定した場合、ラムダ式で関数を設定した場合を比較してみましょう。

defで関数を設定した場合

【結果】

ふつうにaを2倍にするだけです。
これだけのためにわざわざ関数名に「times」という名前をつけているのでちょっとめんどうですよね。

ラムダ式で関数を設定した場合

【結果】

結果はdefを使った場合と同じです。

このように、ラムダ式を使うと「ささっ」っと関数に名前を付けることなく処理を書くことができます。

引数は2つ以上でも良い

関数に渡す引数は2つ以上でも構いません。

前回の記事でも計算した「薄肉円筒の応力」の計算についてです。

【結果】

↓こちらをラムダ式に書き換えてみましょう。

【結果】

sigma_theta自体はラムダ式のオブジェクトとして生成されています。

ラムダ式は複数行の処理を書く定義ができないので、複数行処理を書く場合は関数を使う方が良いでしょう。

map()関数をラムダ式で書く

別の例としてmap()関数をラムダ式で書いてみましょう。

map()関数は、以下のように書いてイテレータとして返ってきます。

シーケンスとは、複数の値を順番に並べたものをひとかたまりとして格納するための型のことです。

  • リスト
  • タプル
  • range
  • 文字列

では、実際にmap()関数を使ってコードを書いてみましょう。

defを使って書く場合

【結果】

sample_listでリストを要します。
やりたいことをリスト内の要素を2倍して10足すということです。
そのために、わざわざ関数[times(a)]を用意して、
「sample_times_list = map(times, sample_list)」としています。

※ちなみにmap()関数で返ってくるのはイテレータです。

イテレータって何かというと「データの流れを表現するオブジェクト」を意味します。
つまり、オブジェクトなのですね。

なのでそのままでは要素の値がわからないので、「list(sample_times_list)」としてリストにしています。

ラムダ式で書く場合

【結果】

ラムダ式で書けば、defの関数を丸々書かなくても、map()関数の第一引数にラムダ式の関数を書くだけで良いのでコード量が少なくて済みます。

filter()関数をラムダ式で書く

filter()関数もラムダ式で書くととても便利です。

filter()関数も、map()関数同様に以下のように書いてイテレータで返ってきます。

 

実際にコードを書いてみましょう。

【結果】

sample_listの要素の、「lambda x: x % 2 == 0」でTrueになったものだけを、sample_list_evenに代入しています。

最後に、リストにするためにlist(sample_list_even)としています。

ジェネレーター

次は、ジェネレーターの解説をします。

ジェネレータとは、Pythonのシーケンスを作成するオブジェクトのことですね。

  • シーケンス:複数の値を順番に並べたものをひとかたまりとして格納するための型
  • ジェネレータ:反復のたびにシーケンスの最後にどこを呼び出されていたかを記憶していて、次の値を返す

range()関数なんかがジェネレータ関数です。

言葉で説明してもよくわからないので、とりあえずコードを書いてみましょう。

普通にprint文でリスト型要素を出力

【結果】

これにより、リスト型の要素がひとつひとつ取り出されたのがわかりますね。

print文をreturnにする

【結果】

結果は、リストの一つ目の要素だけが出力されました。

print文をyieldにする

先ほどのprint文のように、次の要素を出力する場合は、return文の代わりにyieldで戻り値を返すようにします。

【結果】

「next_time」というジェネレータオブジェクトが生成されているので、next()関数を使って次の値、その次の値・・・・・と順番に出力することができます。

デコレーター

デコレータとは、既存のソースコードを書き換えずに、関数に機能を追加したり変更したりできる機能のことです。

まずは、デコレータを使わない例から見てみましょう。

デコレータを使わない例

【結果】

def hello()でhello()関数を定義して、「おはようございます。」と出力するようにしています。

def hello_add(func)で何か関数を渡して、
print(“今日はいい天気ですね!”)
を追加する処理を書いています。

最後に、hello = deco(hello)でhello()関数を上書きしています。

デコレータを使う例

これをデコレーターを使うと以下のようになります。

【結果】

ちょっと記述が簡単になったのがわかりますかね?
変更点は以下です。

「@hello_add」を書く代わりに、「hello = deco(hello)」のコードが不要になりました。

まとめ

今回は、以下の解説を行いました。

この記事で学んだこと
  1. ラムダ式:小さな処理を書く
  2. ジェネレーター:1つずつ取り出す処理(yield関数)
  3. デコレーター:関数に機能を追加

おすすめ参考書

独習Python

独習Python

山田 祥寛
2,970円(11/21 10:41時点)
発売日: 2020/06/22
Amazonの情報を掲載しています
現場ですぐに使える! Pythonプログラミング逆引き大全 357の極意

現場ですぐに使える! Pythonプログラミング逆引き大全 357の極意

俊哉, 金城
9,251円(11/21 16:18時点)
Amazonの情報を掲載しています
関連記事もどうぞ

COMMENT

メールアドレスが公開されることはありません。 が付いている欄は必須項目です