この記事では、python に関する関連知識を提供します。主に関数型プログラミング、つまり命令型パラダイムに関連する問題を紹介します。コンピューターに一連の命令を提供し、それらを実行して完了します。このタスクが皆さんのお役に立てば幸いです。
推奨学習: Python 学習チュートリアル
この記事では、関数型パラダイムとは何か、Python Do の使用方法を学習します。関数型プログラミング。また、リスト内包表記やその他の形式の内包表記についても学習します。
命令型パラダイムでは、コンピューターに一連の命令を与えて実行することによってタスクが達成されます。これらの命令を実行すると、特定の状態が変更される可能性があります。たとえば、最初に A を 5 に設定し、その後 A の値を変更したとします。このとき、変数の内部値という意味でAの状態を変更します。
関数型パラダイムでは、コンピューターに何をすべきかを指示するのではなく、それが何であるかを指示します。たとえば、数値の最大公約数は何か、1 から n までの積は何か、などです。
したがって、変数は変更できません。一度変数を設定すると、その状態が永久に維持されます (純粋な関数型言語では変数は変数ではないことに注意してください)。したがって、関数型プログラミングには副作用はありません。副作用とは、関数がそれ自体以外のものを変更することです。典型的な Python コードの例をいくつか見てみましょう:
このコードの出力は 5 です。関数パラダイムでは、変数を変更することは絶対に禁止されており、スコープ外のものに影響を与える関数を使用することもまた禁止です。関数ができることは、何かを計算して結果として返すことだけです。
今、あなたはこう考えているかもしれません:「変数も副作用もないの? なぜこれが良いの?」 これは良い質問ですが、ほとんどの人がこれについて混乱していると思います。
同じパラメータを使用して関数が 2 回呼び出された場合、同じ結果が返されることが保証されます。数学関数を勉強したことがあれば、その利点がわかるでしょう。これを参照透明性と呼びます。関数には副作用がないため、何かを計算するプログラムを構築する場合、プログラムを高速化できます。 func(2) を呼び出すたびに 3 が返される場合は、それをテーブルに保存することで、プログラムが同じ関数を繰り返し実行するのを防ぐことができます。
通常、関数型プログラミングではループを使用しません。再帰を使用します。再帰は数学的な概念で、通常は「自分自身を呼び出す」ことを意味します。自分自身を繰り返し呼び出す再帰関数をサブ関数として使用します。 Python の再帰関数の良い例を次に示します。
一部のプログラミング言語は遅延型でもあります。これは、最後の 1 秒まで計算や何も行わないことを意味します。 2 2 を実行するコードを作成した場合、関数プログラムは実際に結果を使用する必要がある場合にのみ計算を行います。 Python の遅延についてはすぐに調べます。
理解するために、まず反復とは何かを見てみましょう。通常、反復処理できるオブジェクトはリストまたは配列ですが、Python には反復処理できるさまざまな型があります。マジック メソッドを実装することで反復できる独自のオブジェクトを作成することもできます。マジック メソッドは、オブジェクトをより Python らしくするのに役立つ API のようなものです。オブジェクトを反復可能にするには、2 つのマジック メソッドを実装する必要があります。
最初のマジック メソッド "__iter__" (注: ここでは二重アンダースコア) は反復可能なオブジェクトを返します。これは通常、ループの先頭で使用されます。 「__next__」は次のオブジェクトを返します。
すぐにターミナルに入り、上記のコードを呼び出してみましょう:
実行すると
# と出力されます。 ##Python では、イテレータは __iter__ マジック メソッドのみを持つオブジェクトです。つまり、オブジェクト内の場所にはアクセスできますが、オブジェクトを横断することはできません。コレクションなど、一部のオブジェクトには、 __iter__ マジック メソッドではなく、マジック メソッド __next__ があります (この記事で後述します)。この記事では、私たちが触れるものはすべて反復可能なオブジェクトであると仮定します。 反復可能オブジェクトとは何かを理解したので、map 関数に戻りましょう。 map 関数を使用すると、反復可能オブジェクト内の各項目に関数を適用できます。 Map には、適用される関数と反復可能なオブジェクトの 2 つの入力が必要です。 次のような数値のリストがあるとします。各数値を 2 乗したい場合は、次のコードを記述できます。
Python の関数関数は遅延します。 「list」を使用しない場合、関数はリスト自体の代わりに iterable の定義を保存します。使用するには、Python に「これをリストに変換する」ように明示的に指示する必要があります。
Python で非遅延評価から遅延評価に突然切り替えるのは少し奇妙です。命令型の考え方ではなく関数型の考え方で考えれば、最終的にはそれに慣れることができます。
「square(num)」のような通常の関数を書くのは良いのですが、それは正しくありません。マップで使用するには完全な関数を定義する必要がありますか?さて、ラムダ(匿名)関数を使用してマップ内に関数を定義できます。
ラムダ式は 1 行だけの関数です。たとえば、次のラムダ式は指定された数値を 2 乗します:
実行してみましょう:
#これは見えませんか関数のようなものですか? まあ、これは少し混乱しますが、説明は可能です。変数「square」に何かを代入します。これはどうでしょうか: # これがラムダ関数であり、入力が x であることを Python に伝えます。コロン以降は入力に対して行われるものであり、自動的に結果が返されます。 正方形のプログラムを 1 行のコードのみに単純化するには、次のようにします。 したがって、ラムダ式では、すべてのパラメーターが左、あなた あなたが一緒に作りたいものは右にあります。ちょっと面倒です。しかし真実は、他の関数型プログラマにしか読めないコードを書くことには、ある程度の楽しさがあるということです。また、関数を取得してコード行に変換するのは非常にクールです。フィルターを使用すると、次のように記述できます: 継続的に開発と普及が行われている言語として、Python は今も更新され続けています。勉強するときは、より良い結果を得るために、一緒に勉強したり話し合ったりできる学習パートナーを見つけることをお勧めします。 Python を学習したい場合は、Python 学習交流グループ (627012464) に参加して、一緒に指導し、学習してください。開発ツール、共有すべき多くの役立つ情報、技術情報が含まれています。
関数の結果として返される
Python のすべての関数は高階関数として使用できます。
部分適用 (クロージャとも呼ばれます) は少し奇妙ですが、非常に優れています。必要なパラメータをすべて指定しなくても関数を呼び出すことができます。これを例で見てみましょう。次のように、基数と指数の 2 つの引数を取り、基数を指数で乗じて返す関数を作成したいとします。べき乗関数を使用して数値の 2 乗を求める専用の 2 乗関数:
これは機能しますが、3 乗関数が必要な場合はどうなるでしょうか。あるいは 4 乗の関数を求めるのはどうでしょうか?彼らについて書き続けてもいいでしょうか?まあ、できます。しかし、プログラマーは怠け者です。同じことを何度も繰り返している場合、それは、同じことを繰り返さないように、物事をスピードアップするためのより迅速な方法があることを示しています。ここでクロージャーを使用できます。クロージャを使用した二乗関数の例を見てみましょう:
# すごいですね! 2 つのパラメータを必要とする関数を 1 つのパラメータだけで呼び出すことができます。
ループを使用して、立方体の累乗を 1000 まで実装する累乗関数を生成することもできます。
関数型プログラミングは Python ではありません関数型プログラミングでやりたいことの多くは、それがすべてであることに気づいたかもしれません。リストについて。 Reduce 関数とクロージャを除いて、表示されるすべての関数はリストを生成します。 Guido (Python の父) は Python の関数式を好みませんでした。Python にはすでにリストを生成する独自の方法があったからです。これは Python の禅です。これはPython的であることが何を意味するのかについての詩です。私たちがカバーしたい部分は次のとおりです:
#それを行うための明白な方法は 1 つ、できれば 1 つだけあるはずです (明白な解決策を 1 つ、できれば 1 つだけ見つけるように努めるべきです)
In Python、マップ、フィルターはリスト内包表記と同じ操作を実行できます (後述)。これは Python の禅のルールの 1 つを破っているため、関数型プログラミングのこれらの部分は「Python 的」とはみなされません。 もう 1 つのトピックは Lambda です。 Python では、ラムダ関数は通常の関数です。ラムダは糖衣構文です。これら 2 つのステートメントは同等です。通常の関数は、ラムダ関数で実行できるすべてのことを実行できますが、その逆はできません。 Lambda 関数は、通常の関数で実行できるすべてのことを実行できるわけではありません。
これは、関数型プログラミングが Python エコシステム全体にうまく適合しない理由の簡単な議論です。先ほどリスト内包表記について言及したことにお気付きかもしれませんが、それについてはこれから説明します。
リスト内包表記
先ほど、マップまたはフィルターで実行できることはすべてリスト内包表記を使用できると述べました。リスト内包表記は、Python でリストを生成する方法です。構文は次のとおりです:リスト内の各数値を 2 乗してみましょう。例:
どうするかがわかります。リスト内の各項目に関数を適用します。フィルターを適用するにはどうすればよいですか?前のコードを見てください:
これを次のようにリスト内包表記に変換できます:
List Supports if のようなステートメント。望むものを得るために何百万もの関数を何かに適用する必要はもうありません。実際、ある種のリストを生成したい場合は、リスト内包表記を使用した方がすっきりしていて簡単だと思われます。リスト内の 0 未満のすべての数値を 2 乗したい場合はどうなるでしょうか?ラムダ、マップ、フィルターを使用すると、次のように記述します:
これは非常に長くて複雑に思えます。リスト内包表記の場合は次のようになります。
リスト内包表記はリストに対してのみ機能します。マップとフィルターはあらゆる反復可能なオブジェクトに適していますが、これは何に使用されるのでしょうか?遭遇した反復可能なオブジェクトに対しては、任意の推論を使用できます。
任意の反復可能なオブジェクトの導出を作成できます。
反復可能なオブジェクトは、導出を使用して生成できます。 Python 2.7 以降では、辞書 (ハッシュマップ) を生成することもできます。
反復可能であれば生成できます。最後の一連の例を見てみましょう。
set は、どの要素も 2 回繰り返されない要素のリストです。
セット内の要素には順序がありません。
set には dict と同じ中括弧があることに気づくかもしれません。 Python は非常に賢いです。 dict に値を指定するかどうかに応じて、dict 演繹を記述しているのか、または set 演繹を記述しているのかがわかります。
推奨学習: Python チュートリアル
以上が一緒にPython関数プログラミングを分析しましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。