2012-07-11 13 views
16

これはおそらく愚かな質問ですが、the mapping of operators to functionsを見ると、not in演算子を表す関数がないことに気付きました。最初は私がこれはおそらく解釈者がこれをnot x in yに並べ替えるためだと考えましたが、not inとまったく同じように動作するように思われるis notの機能があります。私は何かを逃しているのですか?そのオペレータは本当に存在しませんか?ここでpython演算子、 "not in"の演算子なし

は、あなたがこれをお勧めします本当に愚かな例です:もちろん

def compare_iter(a,b,func): 
    return [func(aa,bb) for aa,bb in zip(a,b)] 

my_compare=compare_iter(xx,yy,lambda x,y:x not in y) #lambda -- yuck 
my_compare=map(operator.not_,compare_iter(xx,yy,operator.contains) #extra map? grr... 
#it would be nice to do: my_compare=compare_iter(xx,yy,operator.not_contains) 

私はこのために私自身の関数を書くことができますが、オペレータモジュールが出て、このコードをプッシュすることができ、一方、その後、あなたは効率の価格を支払いますしたがって、より速く実行されます。

+0

実際、「a is not b」は単に「not a is b」と並べ替えられませんでしたか? – JAB

+0

'not in'のチェックが 'in'のチェックよりも速く実行できる状況がありますか? –

+1

@PaulMantaは疑いがあります。なぜなら、 'not in'は定義上の網羅的な検索であるからです。 –

答えて

14

ここで、別の機能は必要ありません。あなたは以下のマッピングを持っているのでnot inは、inの逆です:

obj in seq => contains(seq, obj) 

obj not in seq => not contains(seq, obj) 

あなたはアイデンティティ・テストが対称でなければなりませんので、右これは、is/is notと一致していないです。これは設計上の成果物である可能性があります。

+1

これについて考えると、別の演算子*が必要であるはずです。 'x> y'はPythonでは(必然的に)' not(x <= y) 'を意味しません。なぜ封じ込め検査が違うのでしょうか? – mgilson

3

あなたは演算子を理解するために役立つことが、次の機能や解体を見つけることがあります。

>>> def test(): 
     if 0 in(): pass 
     if 0 not in(): pass 
     if 0 is(): pass 
     if 0 is not(): pass 
     return None 

>>> dis.dis(test) 
    2   0 LOAD_CONST    1 (0) 
       3 LOAD_CONST    2 (()) 
       6 COMPARE_OP    6 (in) 
       9 POP_JUMP_IF_FALSE  15 
      12 JUMP_FORWARD    0 (to 15) 

    3  >> 15 LOAD_CONST    1 (0) 
      18 LOAD_CONST    3 (()) 
      21 COMPARE_OP    7 (not in) 
      24 POP_JUMP_IF_FALSE  30 
      27 JUMP_FORWARD    0 (to 30) 

    4  >> 30 LOAD_CONST    1 (0) 
      33 LOAD_CONST    4 (()) 
      36 COMPARE_OP    8 (is) 
      39 POP_JUMP_IF_FALSE  45 
      42 JUMP_FORWARD    0 (to 45) 

    5  >> 45 LOAD_CONST    1 (0) 
      48 LOAD_CONST    5 (()) 
      51 COMPARE_OP    9 (is not) 
      54 POP_JUMP_IF_FALSE  60 
      57 JUMP_FORWARD    0 (to 60) 

    6  >> 60 LOAD_CONST    0 (None) 
      63 RETURN_VALUE   
>>> 

あなたが見ることができるように、各オペレータの違いがあります。そのコードは(順番に)6,7,8,9です。

+2

はい、しかし、あなたが 'not 0 in()'を実行すると、 'not in()'に変換されます - これは、演算子モジュールに対応する演算子が 'not in'はっきりとはっきりとした(そしてさらに好ましい)通訳者です... – mgilson

+2

@mgilson:ちょうど自分自身に気付きました。私はそれが別の方法かもしれないと考えましたが、それは私が今あなたの意見に同意していることがわかります。興味深いことに、公式のPythonメーリングリストでは、そのオペレータの有用性についての議論があるにもかかわらず、「演算子」のメンバーとして「not in」を含むことについて議論することはできません。 – JAB

+1

@JAB、有用性に関するいくつかのディスカッションへのリンクを投稿できますか? (この質問は主に私にとって学問的でしたが、他の人が実際のユースケースについて考えることが大好きです)追加をリクエストする方法はありますか? – mgilson