2012-01-27 7 views
2

Pythonでall()文を短絡する方法はありますか?Pythonの短絡回路all()文

したがって、このような何か:xが0であれば

return all([x != 0, 10/x == 2, True, False, 7]) 

はエラーを返していないのだろうか?

答えて

6

allが呼び出される前にリスト(つまり、すべてのアイテム)が評価されるため、これは機能しません。あなた、この特定のケースでは最良の選択肢は、このようなものです:

return x != 0 and 10/x == 2 and True and False and 7 

私はすでにこのことを知っていると仮定ので、私は、リスト項目がハードコードされていない場合にも適用することができ、別の、より一般的なソリューションを提供します:

return all(f() for f in [lambda: x != 0, lambda: 10/x == 2, 
         lambda: True, lambda: False, lambda: 7]) 

このようにして、式は短絡回路allでのみ評価されます。

1

はい。 x == 0の場合はfalseにしたい場合:

all([x != 0, x!=0 and 10/x == 2, True, False, 7]) 

各値が任意の値xに許可されていることを確認してください。

3

これは、Pythonが結果の値を関数に渡す前にすべての関数の引数を評価するので、これを想像すると正確に動作しません。つまり、allを呼び出す前に、10/x == 2を1つの値に評価します。 (これをMathematicaと比較すると、評価されていない条件が10/x == 2になります)、

このリストをallに渡すことを知っているとすれば、最も簡単なことは、ちょうどPythonのandオペレータの短絡機能を使用します。それは、ゼロで

return all([x != 0, 10 == 2 * x, True, False, 7]) 

を分割しないように

return all([x != 0 and 10/x == 2, True, False, 7]) 

別の方法としては、数学的な条件を書き換えることができ(floaに気を付けますティンポイント部門の問題)。

評価されていない条件を渡す動作を実際にエミュレートしたいのであれば、私が考えることができる唯一の方法は、呼び出し時に条件を評価する呼び出し可能オブジェクトを渡すことです。たとえば、ラムダ関数にすべてのあなたのリストの要素を変換することができます:

return all(f() for f in [lambda: x != 0, lambda: 10/x == 2, 
        lambda: True, lambda: False, lambda: 7]) 

あなたが関数にすべてを変換したくない場合は、私はあなただけ呼び出すラッパーのいくつかの並べ替えを考え出すことができると思います実際に呼び出し可能ですもの:

return all(f() if callable(f) else f in [x != 0, lambda: 10/x == 2, 
                True, False, 7]) 

が、(あなたは、Python :-PでCASを書いているのでない限り)正直、それは混乱のように思えます。

+2

ニーストリック:) –

6

あなたのコードは、発電機にあった場合、あなた可能性も短絡のものこの方法:第二の例では

def test(x): 
    yield x != 0 
    yield 10/x == 2 
    yield True 
    yield False 
    yield 7 

all(test(9))