2012-05-05 12 views
1

次のコードを書いています。渡す数値が1、0または2の文字列で、それ以外はすべてfalseの場合は、yesを出力します。PythonでのORの振る舞い:

number=raw_input() 
if number is "1" or "0" or "2": 
    print "Yes" 
else: 
    print "no" 

は私が意図したロジックの仕事を作る方法を知っているが、私はちょうどそれは私がraw_inputに渡す任意の数のためにはい印刷し、なぜ 必要 が知りたいです。私はそれが失敗する理由を理解カントので答えは、できるだけ詳細になりたい、それが私には十分なニシキヘビのようだ

答えて

4

問題は、Pythonのコードが、次のように読み込むことです:

if (number is "1") or "0" or "2": 

空でない文字列はTrueと評価され、常にTrueです。 、あなたが何をしたいの素敵な構文を行うに

は次のとおりです。

if number in {"1", "0", "2"}: 

は、ここで設定したの私の使用に注意してください - それは(3つの値のみを持つ)この場合はあまり問題ではありませんがチェック集合に対するメンバシップ・テストはO(n)ではなくO(1)であるため、集合に対してはリストより高速です。

これは単によりよい、これを書くのが容易:あなたが望んで

if number == "1" or number == "0" or number == "2": 

メモ値を比較するときは、必ず==を使用しないでください。is - isは同一性チェックです(2つの値は同じオブジェクトです)。一般的にis Trueis Noneのようなものにはisを使用してください。

あなたは数としてこれを処理したい場合は、このような何か行うことができます:あなたは数字の広い範囲に比較したい状況で、より有用である可能性

try: 
    value = int(number) 
except ValueError: 
    value = None 
if value is not None and 0 <= value <= 2: 
    ... 

を。 Pythonの便利な比較チェイン(0 <= value and value <= 2ではなく0 <= value <= 2)を使用していることに注意してください。

+0

set literal(Python 2.7以降で利用可能)の場合は+1、 'is'を使用した文字列比較の警告の場合は+1。 – modocache

+0

ありがとうございました...特に最後のメモのために、私はそれを知らなかった。 –

0

orの間のすべての式はブール式として評価されるため、

if Trueと評価された場合、if 1:はTrueと評価され、if "0":はTrueと評価されます。あなたが書いただから何

は、多かれ少なかれ相当:

if number is "1": 
    print "Yes" 
elif "0": 
    print "Yes" 
elif "2": 
    print "Yes" 
else: 
    print "no" 

あなたが書かれているはずですif number is "1" or number is "0" or number "2":または、より多くのニシキヘビ:if number in ("1", "0", "2"):

2

正しい構文は次のとおりです。

if number == "1" or number == "0" or number == "2": 
    print "Yes" 

またはその他のPythonic:

if number in ["1", "2", "3"]: 
    print "Yes" 

それとも、intにキャストして試すことができます:

if int(number) in range(1,4): 
    print "Yes" 

あなたのコードがTrueに評価された理由は、それが文として当てはまる"0""2"の真実を評価しているため、すべての時間がありますPython。

+0

これはリストを使うのは良い考えではないことに注意してください。リストのメンバーシップチェックは遅く、セットを使うのが理にかなっています。入力が潜在的に数字でないものになる可能性がある場合は、最後の例で例外がスローされます。 –

+0

私は例外の可能性を認識していましたが、リストメンバーシップのチェックではパフォーマンスが低下しませんでした。ヒントをありがとう! – modocache