String comparison in Python: is vs. ==

The Question :

563 people think this question is useful

I noticed a Python script I was writing was acting squirrelly, and traced it to an infinite loop, where the loop condition was while line is not ''. Running through it in the debugger, it turned out that line was in fact ''. When I changed it to !='' rather than is not '', it worked fine.

Also, is it generally considered better to just use ‘==’ by default, even when comparing int or Boolean values? I’ve always liked to use ‘is’ because I find it more aesthetically pleasing and pythonic (which is how I fell into this trap…), but I wonder if it’s intended to just be reserved for when you care about finding two objects with the same id.

The Question Comments :
  • How is this “counter to your experience”? NaN is the only built-in counterexample; you’re simply misunderstanding directional relations. The spec says “For all built-in Python objects (like strings, lists, dicts, functions, etc.), if x is y, then x==y is also True.”, not “For all built-in Python objects (like strings, lists, dicts, functions, etc.), if x==y, then x is y is also True.” For some reason, you’re pretending it says the latter. It doesn’t. You see that equality matches, but is doesn’t. That is perfectly allowed by the former quoted statement.
  • Yup. My reading of that was completely confused. I edited it out of the question, because I don’t think it will be useful to future readers.
  • o1 is o2 => compares if o1 and o2 both points to same physical location in memory (in other words if they are same object). While, o1 == o2 => here python call the o1’s __cmp__(o2) method, which ideally should compares the value and return True or False. (In other words it compares value) For JAVA people: In Java, to determine whether two string variables reference the same physical memory location by using str1 == str2. (called object identity, and it is written in Python as str1 is str2). To compare string values in Java, usestr1.equals(str2); in Python, use str1 == str2.

The Answer 1

630 people think this answer is useful

For all built-in Python objects (like strings, lists, dicts, functions, etc.), if x is y, then x==y is also True.

Not always. NaN is a counterexample. But usually, identity (is) implies equality (==). The converse is not true: Two distinct objects can have the same value.

Also, is it generally considered better to just use ‘==’ by default, even when comparing int or Boolean values?

You use == when comparing values and is when comparing identities.

When comparing ints (or immutable types in general), you pretty much always want the former. There’s an optimization that allows small integers to be compared with is, but don’t rely on it.

For boolean values, you shouldn’t be doing comparisons at all. Instead of:

if x == True:
    # do something

write:

if x:
    # do something

For comparing against None, is None is preferred over == None.

I’ve always liked to use ‘is’ because I find it more aesthetically pleasing and pythonic (which is how I fell into this trap…), but I wonder if it’s intended to just be reserved for when you care about finding two objects with the same id.

Yes, that’s exactly what it’s for.

The Answer 2

260 people think this answer is useful

I would like to show a little example on how is and == are involved in immutable types. Try that:

a = 19998989890
b = 19998989889 +1
>>> a is b
False
>>> a == b
True

is compares two objects in memory, == compares their values. For example, you can see that small integers are cached by Python:

c = 1
b = 1
>>> b is c
True

You should use == when comparing values and is when comparing identities. (Also, from an English point of view, “equals” is different from “is”.)

The Answer 3

70 people think this answer is useful

The logic is not flawed. The statement

if x is y then x==y is also True

should never be read to mean

if x==y then x is y

It is a logical error on the part of the reader to assume that the converse of a logic statement is true. See http://en.wikipedia.org/wiki/Converse_(logic)

The Answer 4

26 people think this answer is useful

See This question

Your logic in reading

For all built-in Python objects (like strings, lists, dicts, functions, etc.), if x is y, then x==y is also True.

is slightly flawed.

If is applies then == will be True, but it does NOT apply in reverse. == may yield True while is yields False.

Add a Comment