とまと あんらいぷ…

エンジニアの活動記録とかつぶやきとか

GitHub

Pythonのラムダ式はfunctionで光る

WindowsでPython シリーズ その17


前回ラムダ式をやってみたけど、C#におけるLINQみたいに扱うことができるのが真骨頂だった。
これってどっちが真似してるんでしょうね。

map関数


pythonのマニュアルを見て、functionという言葉が出てきたら
「ラムダ式だ!」と考えるクセをつけておくのがいいかもしれない。
map関数の説明を見てみる。

function を、結果を返しながら iterable の全ての要素に適用するイテレータを返します。
なんのこっちゃ。
C#プログラマなら分かるかもしれない。これはLINQにおけるSelect()なのだと。
function って関数のことだから、無名関数であれ定義された関数であれ、
要するに関数ポインタを引数として渡すことができるんだよね。

要約すると、
map関数の第1引数には"関数(引数付き)"を指定してね。
第2引数で指定したリストの全部を、第一引数の関数に放り込んだ結果のオブジェクト(の場所?)を返却するよ。
こういうことなんでしょう。
戻り値はアドレスなので、それを適切に変換してやる。
つまりリストにキャストすると、人間にはその値が確認できます。

コードはこんな感じ。


結果
PythonMAP関数でラムダ式を使う

戻り値をlistに変換してるのがそれです。
コレをキャストしない場合は・・・何やらオブジェクトのアドレスが出てますね。

filter関数


filter関数はC#:LINQのwhereみたいなもんですね。
説明は以下
iterable の要素のうち function が真を返すものでイテレータを構築します。
つまり、リストとか辞書とか、タプルもいけるんかな?とにかくforで繰り返し項目にしていできるもんのうち
第一引数で指定した関数の結果のみを返却するよ!ってことですね。

例えば100以上とか。そういうのがfilterです。

コードとしては以下

先程map関数で第一引数の関数結果を返却したけど、今度は関数結果がtrueになるものだけを抽出するリストを返す。
そんな関数です。

結果
Pythonのfilter関数でラムダ式を使う

map関数の場合は関数の実行結果がみてとれます。
対してret3は、ラムダ式で指定した値に合致する値がリストとして取れてますね。

これはすごいぞ!

さいごに


ラムダ式はC#のLINQに似ている。
多分ラムダを使いこなすとすごいエレガントなコードになるんだろうな。
今は無理だけど基本構造を覚えていって立派なpythonerになりたいですね。

pythonにおけるラムダ式の書き方

WindowsでPython シリーズ その16


pythonではlambdaキーワードを使うと、ラムダ式が使えるようです。
数年前に流行りだした(?)ラムダ式。
C#プログラマには朗報なのかも。

そもそもラムダ式ってなんだよ


ラムダ式は、無名関数を簡単に定義できる構文です。
ラムダ式の前に、まずは関数を変数に代入できることを理解する必要があります。

こんな感じ。


実行結果
pythonにおけるラムダ式の書き方

変数定義を冒頭でしていますが、その変数を引数なしで変数に代入しています。
その後、変数に引数を与えて呼び出すと、関数のように振る舞ってますね。
これが前提

ラムダ式の書き方


先の例では、sum_num 関数を定義して、それを変数に代入していました。
でも、こんな処理がショボい関数をいちいち定義したくない。

そんな理由で、プログラム中にチョロチョロっと処理をまとめたい時に登場するのが
無名関数「lambda式」の登場です。
先と同じ処理をラムダ式を使って書いてみます。


実行結果
pythonにおけるラムダ式の書き方

はい、関数定義するよりもスッキリ書くことができました。
ただ、多用すると関数定義よりもコードが読みにくくなります。
同じような処理のラムダをたくさん書くのであれば、素直に関数定義したほうがよいでしょう。
あくまでも無名関数:ラムダは構文を簡単にしたもの(シンタックスシュガー)なのでコーディング時はセンスが求められますね。

ラムダ式の書き方まとめ


  • ラムダ式は lambda キーワードを使う

  • return は書かない

  • ()も書かない

  • "ラムダ"と読んでるけど、bがいりますからね。"lambda"です。

    いやぁ、、、それにしてもこの言語どうなってんだろ。便利な機能多すぎですね。

    pythonのglobal変数の挙動確認

    WindowsでPython シリーズ その15



    本日はPythonにおけるglobal変数について挙動確認しました。

    グローバル変数の書き方


    変数については過去のエントリで多少かいてますが、
    pythonでもグローバル変数が存在します。

    関数の中以外で宣言すればそれはグローバルになるわけですが
    pythonではglobalキーワードを使えば、それがglobal変数として認識されるようです。



    実行結果
    pythonのglobal変数の挙動確認

    まず、glovar = "グローバルだよ"で、グローバル変数として指定しています。
    この変数はプログラムのドコからでも参照できます。

    次に defを使って関数を2つ宣言

    global_change() で、global変数で"あろう"変数に値をセットしています。
    ですがこの関数を呼出後、glovarをprint()しても "グローバルだよ"という結果になります。
    これは、見ての通り、関数の中で宣言したglovarは、
    あくまでも関数の中で宣言した変数に対しての処理という扱いだからですね。
    これをローカル変数といいます。

    同じ名前の変数を宣言して、バグにならないようにしてるということです。

    関数内でglobal変数を操作する


    次にglobal_change2() では、global変数で"あろう"変数に値をセットしています。
    その前に、global glovar と書いて、関数内のglovarはグローバルなのだと指定しています。

    結果として、"ローカルだよ"という出力。
    これは、グローバル変数がローカル変数ではないという事を宣言できた結果ですね。

    pythonでは、グローバル変数はきちんと明示する


    今日はこれでおしまいですが、
    pythonに限らずグローバル変数は意識して使わないと、バグのもとになりますので、
    ローカル変数内で明示的に指定させるプログラムの仕様はいいなと思いました。

    ではでは!



    Python 関数における可変長引数の書き方

    WindowsでPython シリーズ その14


    前回はPython 関数の定義とヘルプの書き方をやりましたが
    関数の書き方をもう少し掘り下げておきます。

    可変長引数とはなにか


    可変長引数というのは、引数の数を変えられるということです。
    可変長引数を指定するには「*args」というように、引数の前に「*」を付けます。
    こんな感じ。


    実行結果
    Python 関数における可変長引数の書き方

    数値を合計する関数を作成してみました。
    ちょっと色気を出して、もし数字以外の文字が指定されたら、数字じゃないよ的なメッセージを表示するようにしています。

    Pythonでは、「*」を付けた引数はタプルとして扱われるようです。
    タプルについては「Pythonのリストとタプルと集合型の違い」を参考ください。

    辞書型の可変長引数


    引数に「*」ではなくて「**」をつけると、引数が辞書型の可変長引数になるみたいです。



    実行結果
    Python 関数における可変長引数の書き方

    ちょっと無理やりコードにしてみたけど、正直使いどころがイマイチわからん・・・いつか役に立つ時が来るかも。

    まとめ


    Pythonでは引数を可変にできる。
    書き方は

    「*」をつけると引数がタプルになる。
    「**」をつけると引数が辞書型になる。

    辞書型の引数の場合は、関数呼出し時に辞書っぽくなるように呼び出す。

    こんな感じかな。

    今日はここまで!ではまた!

    Python 関数の定義とヘルプの書き方

    WindowsでPython シリーズ その13


    とうとう来ました関数定義の巻。
    だんだんプログラミングらしくなってきました。
    関数定義を学習し、冗長的なコードから開放されたいと思います。

    これまでコードの確認にprint()を多様してきました。
    出力結果を見やすくするために無駄にprint()なんて書いてましたけど、関数定義をすることで自動的に改行付きのprint()を実装することができます。

    それではいってみましょう!

    関数定義をする前に


    コーディングを適当にして変なクセが付いてしまうと、後でとても後悔します。
    醜いコードになります。
    なのできちんとコーディング規則に従って関数を定義することに専念します。

    今回参考にするマニュアルはコチラ

  • 4.6. 関数を定義する
  • 4.7.6. ドキュメンテーション文字列
  • 4.8. 間奏曲: コーディングスタイル


  • つまり
    「関数の宣言方法」
    で、書き方を

    「関数の説明(docstring)」
    で、ヘルプ呼び出し時に説明がでるようにして

    「関数の命名規則(コーディング規則」
    で、書くだけじゃなくてキレイに書こう

    ということですね。

    関数定義とdocstring


    docstringとは、その関数の説明書のことです。help(関数名)と書くと表示されます。
    今回はマニュアルにそって関数定義をして、関数の実行とhelpを見てみます。



    実行結果
    Python 関数の定義とヘルプの書き方

    いかがでしょうか。
    printの代わりにprint_and_lineを使うことで、自動改行が行われています。
    さらにdocstringで、helpすればその説明が表示されています。
    書き方は、マニュアルのコーディングスタイルに従って記載しました。
    しかし、完全にルールを守っている訳ではなく、日本語コメントを使ったりしています。(この当たりは日本文化風に・・)

    あと、命名規則には
    self をメソッドの第 1 引数の名前 (クラスやメソッドについては クラス初見 を見よ) として使うこと。
    と書いてるんですが、利用事例を見てるとクラスのメソッドでの利用例がほとんどだったので、関数に関して、第一引数をsとしています。関数でもselfと名付けたほうがいいのかな?
    とまぁ、何より大事なのは一貫性を保つことのようなので、今回はこれでよしとしておきます。

    関数名などは以下に記載のように、lower_case_with_underscores で定義しています。
    インデントには空白 4 つを使い、タブは使わないこと。

    空白 4 つは (深くネストできる) 小さいインデントと (読み易い) 大きいインデントのちょうど中間に当たります。タブは混乱させるので、使わずにおくのが良いです。

    ソースコードの幅が 79 文字を越えないように行を折り返すこと。

    こうすることで小さいディスプレイを使っているユーザも読み易くなり、大きなディスプレイではソースコードファイルを並べることもできるようになります。

    関数やクラスや関数内の大きめのコードブロックの区切りに空行を使うこと。

    可能なら、コメントは行に独立で書くこと。

    docstring を使うこと。

    演算子の前後とコンマの後には空白を入れ、括弧類のすぐ内側には空白を入れないこと: a = f(1, 2) + g(3, 4)。

    クラスや関数に一貫性のある名前を付けること。慣習では CamelCase をクラス名に使い、 lower_case_with_underscores を関数名やメソッド名に使います。常に self をメソッドの第 1 引数の名前 (クラスやメソッドについては クラス初見 を見よ) として使うこと。

    あなたのコードを世界中で使ってもらうつもりなら、風変りなエンコーディングは使わないこと。どんな場合でも、Python のデフォルト UTF-8 またはプレーン ASCII が最も上手くいきます。

    同様に、ほんの少しでも他の言語を話す人がコードを読んだりメンテナンスする可能性があるのであれば、非 ASCII 文字も識別子に使うべきではありません。


    できそうなことが増えてきた


    さて関数を学ぶと、部品を色々つくってゴニョゴニョできそうな気がしてきました。
    そろそろpyファイルをエディタから実行するんじゃなくて、一つのプログラムとして呼び出したいところ・・・
    そんなことできるんかな?
    前のページ 次のページ

    FC2Ad