4

機能的な方法でPython関数を作成しようとしています。問題は、if 条件を関数型スタイルに変換する方法がわからないことです。と の 2 つの変数がAあります。C次の条件をチェックします。

def function():
    if(A==0): return 0
    elif(C!=0): return 0
    elif(A > 4): return 0
    else: someOtherFunction()

ラムダ短絡を見ましたが、動作しませんでした。

よろしくお願いします!

4

4 に答える 4

9

あなたが投稿したリンクから:

FP はステートメントを思いとどまらせるか、完全に禁止し、代わりに式の評価を処理します。

したがって、ステートメントの代わりに、条件式ifを使用できます。

def function():
    return (0 if ((A == 0) or (C != 0) or (A > 4)) else
            someOtherFunction())

または、(特に多くの異なる値がある場合に役立ちます):

def function():
    return (0 if A == 0 else
            0 if C != 0 else
            0 if A > 4 else
            someOtherFunction())

ちなみに、リンクされた記事は提案しています

(<cond1> and func1()) or (<cond2> and func2()) or (func3())

と同等の短縮形として

if <cond1>:   func1()
elif <cond2>: func2()
else:         func3()

問題は、それらが同等ではないことです! ブール式は、 が真であるが偽である場合 (例: または または )、正しい値を返すこと<cond1>func1()できFalseませ0None。(または同様に、<cond2>が Truish であるfunc2が Falsish である場合。)

(<cond1> and func1())

func1()は、 when is Trueishを評価する意図で書かれています<cond1>が、 when func1()is Falsish は に(<cond1> and func1())評価されるFalseため、式全体が渡され、Python は(<cond2> and func2())ショートサーキットの代わりに評価を続けます。

というわけで、ちょっと興味深い歴史をご紹介します。2005 年に、 Raymond Hettingertype(z)==types.ComplexType and z.real or zはwhen z = (0+4j)because z.realis Falsishで同様の見つけにくいバグを発見しました。同様のバグから私たちを救いたいという願望に動機付けられて、エラーが発生しにくい構文(条件式) を使用するというアイデアが生まれました。

于 2012-11-03T12:40:10.410 に答える
4

現在のコードには、「機能的スタイル」以外のものはありません! とにかく条件は機能しないと誰が言ったのですか? cond実際にはすべての関数型言語には、Lispの特殊な形式など、何らかの条件演算子があります。

コードが代入演算子を使用している場合、または何らかの方法で状態を変更している場合(たとえば、リストに追加する場合)、コードに問題がありますが、そのままでは、問題の関数はすでに「関数型」になっています-そこに状態の変更はありません。

もしかして、こういう意味だったの?

return A != 0 and C == 0 and A <= 4 and someOtherFunction()

上記は、またはまたはのFalse場合に返されます。それ以外の場合はすべて、呼び出しの値が返されます。ちなみに、は(たとえば)に評価されると想定できるため、問題のコードのセマンティクスは呼び出し元の観点から保持されます。A == 0C != 0A > 4someOtherFunction()False042 + False == 42

リンク内の情報を文脈から切り離していることに注意してください。これにa を使用する必要はまったくありませんlambda。この記事では、Python の s 固有の制限を回避する方法を説明しているだけlambdaです。つまり、(のような) 内でステートメントを返すことはできません。if-elif-else式のみが許可されていますが、偽造することはできます。それらをブール演算子で。通常の関数のコンテキストでは、必ず条件を使用してください。

于 2012-11-03T12:25:17.677 に答える
2

Peter Norvig は本当に素晴らしい人物ですが、彼の Web サイトは検索するのが非常に困難です。

Python で (テスト ? 結果 : 代替) と同等のことができますか?について読んだことを覚えています。機能的なPythonの話の前に、いくつかの調査中に彼のサイトでしばらく前に。

私の調査結果に照らして、何らかの形であなたを動揺させるつもりはありませんが、関数型スタイルの三項条件演算子に関するセクションを読んでください。

def if_(test, result, alternative=None):
    "If test is true, 'do' result, else alternative. 'Do' means call if callable."
    if test:
        if callable(result): result = result()
        return result
    else:
        if callable(alternative): alternative = alternative()
        return alternative
于 2012-11-03T13:06:38.890 に答える
0

そのままお使いください。

Python には、単一の式を直接返すようにすべての関数を簡単にプログラムできるようにするための構文とライブラリの組み込みがありません。とにかく、それは関数型スタイルの最も重要な部分ではありません。最も重要な部分は、関数が参照整合性を維持していることを確認することです。基本的にこれは、同じ入力値を指定すると、同じ出力が返されることを意味します。

したがって、Python で機能的にプログラミングしようとするとき、私はステートメントを完全に使用することを控えません。let ... in ...Haskellと同等のものとして、ローカル変数割り当てのブロックを使用します。caseHaskell の式に相当するものとして、if/elif/else チェーンを使用します。また、インプレースで更新するのではなく、新しい「変更された」バージョンを作成するための適切なインターフェイスを提供しない組み込み型がよくあるため、代わりに明示的なコピー操作でそのような操作を実装し、次にミューテーションを使用する必要があります新しいコピー。

Python では、機能的なスタイルのデザインを直接実装できます。明示的に状態を渡し、副作用を持たない一連の関数としてプログラムを簡単に構築できるため、関数型プログラミング言語で行うのと非常によく似た方法で高レベルのアルゴリズムを設計できます。この意味で、ほとんどすべてのプログラミング言語が関数型プログラミングをサポートしています。ただし、ファースト クラスの関数を偽造するために必要なボイラープレートを受け入れる準備ができている場合です。Pythonにはファースト クラスの関数があるため、ボイラープレートを我慢する必要さえありません。

しかし、それは Python が関数型プログラミングをサポートしている限りです。関数を単一の参照透過式として実装することは実際にはサポートされていません。しかし、それは本当に問題ではありません。純粋性を強制または追跡しない言語では、プログラムを参照透過関数の集まりとして設計するだけで、関数型プログラミングのほとんどすべての利点を得ることができ、それらの関数をどのように実装するかは実際には重要ではありません。インターフェイスが参照透過性を維持している限り。

于 2012-11-03T23:55:37.593 に答える