OR behaviour in python:

I have written the following piece of code, all i want to do is print a yes for if the number passed is a string representation of 1, 0 or 2 and for everything else a false:

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

I know how to make the intended logic work, but i just want need to know why it prints yes for any number i pass to raw_input. I'd like the answer to be as detailed as possible, because i cant understand why it would fail, it seems pythonic enough to me


Solution 1:

The problem is that your code, to Python, reads like this:

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

And as any non-empty string evaluates to True, it's always True.

To do what you want to do, a nice syntax is:

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

Note my use of a set here - while it doesn't matter too much in this case (with only three values) checking against a set is faster than a list, as a membership test for a set is O(1) instead of O(n).

This is simply a nicer and easier of writing this:

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

Which is what you wanted.

Note when making a comparison for value you should always use == not is - is is an identity check (the two values are the same object). Generally you should use is for stuff like is True or is None.

If you wanted to handle this as a number, you could do something like this:

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

Which could be more useful in situations where you want to compare to a large range of numbers. Note my use of Python's useful comparison chaining (0 <= value <= 2 rather than 0 <= value and value <= 2).

Solution 2:

The correct syntax is as follows:

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

Or the more Pythonic:

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

Or you can cast to int and try:

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

The reason your code evaluates to True is all the time is because it is evaluating the truth of the "0" and "2", which as statements are true in Python.