When to use == and when to use is?

Question:

Curiously:

>>> a = 123
>>> b = 123
>>> a is b
True
>>> a = 123.
>>> b = 123.
>>> a is b
False

Seems a is b being more or less defined as id(a) == id(b). It is easy to make bugs this way:

basename, ext = os.path.splitext(fname)
if ext is '.mp3':
    # do something
else:
    # do something else

Some fnames unexpectedly ended up in the else block. The fix is simple, we should use ext == '.mp3' instead, but nonetheless if ext is '.mp3' on the surface seems like a nice pythonic way to write this and it’s more readable than the “correct” way.

Since strings are immutable, what are the technical details of why it’s wrong? When is an identity check better, and when is an equality check better?

Asked By: wim

||

Answers:

As far as I can tell, is checks for object identity equivalence. As there’s no compulsory “string interning”, two strings that just happen to have the same characters in sequence are, typically, not the same string object.

When you extract a substring from a string (or, really, any subsequence from a sequence), you will end up with two different objects, containing the same value(s).

So, use is when and only when you are comparing object identities. Use == when comparing values.

Answered By: Vatine

They are fundamentally different.

  1. == compares by calling the __eq__ method
  2. is returns true if and only if the two references are to the same object

So in comparision with say Java:

  1. is is the same as == for objects
  2. == is the same as equals for objects
Answered By: Petar Ivanov

Simple rule for determining if to use is or == in Python

Here is an easy rule (unless you want to go to theory in Python interpreter or building frameworks doing funny things with Python objects):

Use is only for None comparison.

if foo is None

Otherwise use ==.

if x == 3

Then you are on the safe side. The rationale for this is already explained int the above comments. Don’t use is if you are not 100% sure why to do it.

Answered By: Mikko Ohtamaa

It would be also useful to define a class like this to be used as the default value for constants used in your API. In this case, it would be more correct to use is than the == operator.

class Sentinel(object):
    """A constant object that does not change even when copied."""
    def __deepcopy__(self, memo):
        # Always return the same object because this is essentially a constant.
        return self

    def __copy__(self):
        # called via copy.copy(x)
        return self
Answered By: Trevor McCasland

You should be warned by PyCharm when you use is with a literal with a warning such as SyntaxWarning: "is" with a literal. Did you mean "=="?. So, when comparing with a literal, always use ==. Otherwise, you may prefer using is in order to compare objects through their references.

Answered By: talha06
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.