完全を期すために、in
演算子は属性メンバーシップをテストするブール演算子として使用できます。したがって、 if..else
ステートメントで使用できます(完全なドキュメントの抜粋については以下を参照してください)。
in
演算子を使用する場合、(たとえばobj in container
)インタプリタは最初にメソッドcontainer
がある かどうかを調べます。__contains__
そうでない場合でもcontainer
、メソッドが定義されている__iter__
場合、Pythonはオブジェクトに含まれるすべての値を反復処理し、等しいかどうかをテストします。つまり、基本的に次のようなパフォーマンスを実行します。
for value in container:
if value == obj:
return True
return False
最後に、どちらのメソッドも定義されていない場合、インタープリターは__getitem__
コンテナーを反復処理するメソッドを探し、それでも。を使用して任意の値が等しいかどうかをテストしobj
ます。比較演算子のドキュメントも参照してください。
さて、あなたの場合、range([start], stop[, step])
関数[documentation]は実際にリストを返します(このリストは最後の要素を保持していないことに注意してください)。これはメソッドrange(1, 5) == [1, 2, 3, 4]
を定義します。__contains__
>>> type(range(1, 10))
list
>>> hasattr(list, '__contains__')
True
>>> 4 in range(1, 10)
True
したがって、これは完全に書き込みを許可されていますx in range(1, 10)
。他の回答が指摘しているように、あなたの問題は実際には入力データを整数にキャストすることによって解決される型の問題"3" == 3
です(Falseのように)。ただし、入力値が適切に制限されているかどうかをテストするだけの場合は、比較演算子を使用することを強くお勧めします。
>>> if 1 <= x < 10:
... print 'ok'
... else:
... print 'ko'
見た目が読みやすく、廃止されたリストを作成していないため、メモリフットプリントを最小限に抑えることができます。
xrange
リストの暗黙的な構築を回避するために、リストではなくイテレータを返す関数を使用できます。この場合、値は遅延評価されるため、メソッドxrange
を定義しませんが、メソッドを定義するため、すべてが引き続き行われます。うまくいきます!__contains__
__iter__
>>> type(xrange(1, 10))
xrange
>>> hasattr(xrange, '__contains__')
False
>>> hasattr(xrange, '__iter__')
True
>>> 4 in xrange(1, 10)
True
最後に、演算子に関するPythonドキュメントからの抜粋ですin
コレクションメンバーシップのテストに参加しているオペレーターとテストしていないオペレーター。x in sは、xがコレクションsのメンバーである場合はtrueと評価され、それ以外の場合はfalseと評価されます。sにないxは、sにあるxの否定を返します。コレクションメンバーシップテストは、伝統的にシーケンスにバインドされてきました。コレクションがシーケンスであり、そのオブジェクトと等しい要素が含まれている場合、オブジェクトはコレクションのメンバーです。ただし、他の多くのオブジェクトタイプが、シーケンスでなくてもメンバーシップテストをサポートすることは理にかなっています。特に、辞書(キー用)とセットはメンバーシップテストをサポートします。
リストおよびタプルのタイプの場合、x == y [i]がtrueであるようなインデックスiが存在する場合にのみ、yのxがtrueになります。
Unicodeおよび文字列型の場合、xがyの部分文字列である場合に限り、yのxはtrueになります。同等のテストはy.find(x)!=-1です。xとyは同じタイプである必要はないことに注意してください。したがって、'abc'のu'ab'はTrueを返します。空の文字列は常に他の文字列のサブ文字列と見なされるため、「abc」の「」はTrueを返します。
バージョン2.3で変更:以前は、xは長さ1の文字列である必要がありました。
()メソッドを定義するユーザー定義クラス__contains__
の場合、yのxは、yの場合にのみtrueになります。__contains__
(x)は真です。
__contains__
()を定義しないが()を定義するユーザー定義クラス__iter__
の場合、yの反復中にx == zの値zが生成されると、yのxは真になります。反復中に例外が発生した場合は、その例外が発生した場合と同じです。
最後に、古いスタイルの反復プロトコルが試されます。クラスが()を定義する場合__getitem__
、x == y [i]のような非負の整数インデックスiがあり、すべての下位整数がある場合にのみ、yのxはtrueになります。インデックスはIndexError例外を発生させません。(他の例外が発生した場合は、その例外が発生した場合と同じです)。
inでない演算子は、inの逆の真の値を持つように定義されています。
演算子はオブジェクトの同一性をテストしますが、テストしません。xとyが同じオブジェクトである場合に限り、xはyです。xがyではない場合、逆真理値が得られます。[7]