# Is there a difference between “==” and “is”?

Posted on

Solving problem is about exposing yourself to as many situations as possible like Is there a difference between “==” and “is”? and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about Is there a difference between “==” and “is”?, which can be followed any time. Take easy to follow this discuss.

Is there a difference between “==” and “is”?

In Python, are the following two tests for equality equivalent?

``````n = 5
# Test one.
if n == 5:
print 'Yay!'
# Test two.
if n is 5:
print 'Yay!'
``````

Does this hold true for objects where you would be comparing instances (a `list` say)?

Okay, so this kind of answers my question:

``````L = []
L.append(1)
if L == [1]:
print 'Yay!'
# Holds true, but...
if L is [1]:
print 'Yay!'
# Doesn't.
``````

So `==` tests value where `is` tests to see if they are the same object?

`is` will return `True` if two variables point to the same object, `==` if the objects referred to by the variables are equal.

``````>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
>>> b == a
True
# Make a new copy of list `a` via the slice operator,
# and assign it to variable `b`
>>> b = a[:]
>>> b is a
False
>>> b == a
True
``````

In your case, the second test only works because Python caches small integer objects, which is an implementation detail. For larger integers, this does not work:

``````>>> 1000 is 10**3
False
>>> 1000 == 10**3
True
``````

The same holds true for string literals:

``````>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True
``````

Please see this question as well.

There is a simple rule of thumb to tell you when to use `==` or `is`.

• `==` is for value equality. Use it when you would like to know if two objects have the same value.
• `is` is for reference equality. Use it when you would like to know if two references refer to the same object.

In general, when you are comparing something to a simple type, you are usually checking for value equality, so you should use `==`. For example, the intention of your example is probably to check whether x has a value equal to 2 (`==`), not whether `x` is literally referring to the same object as 2.

Something else to note: because of the way the CPython reference implementation works, you’ll get unexpected and inconsistent results if you mistakenly use `is` to compare for reference equality on integers:

``````>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False
``````

That’s pretty much what we expected: `a` and `b` have the same value, but are distinct entities. But what about this?

``````>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True
``````

This is inconsistent with the earlier result. What’s going on here? It turns out the reference implementation of Python caches integer objects in the range -5..256 as singleton instances for performance reasons. Here’s an example demonstrating this:

``````>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
...
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False
``````

This is another obvious reason not to use `is`: the behavior is left up to implementations when you’re erroneously using it for value equality.

## Is there a difference between `==` and `is` in Python?

Yes, they have a very important difference.

`==`: check for equality – the semantics are that equivalent objects (that aren’t necessarily the same object) will test as equal. As the documentation says:

The operators <, >, ==, >=, <=, and != compare the values of two objects.

`is`: check for identity – the semantics are that the object (as held in memory) is the object. Again, the documentation says:

The operators `is` and `is not` test for object identity: `x is y` is true
if and only if `x` and `y` are the same object. Object identity is
determined using the `id()` function. `x is not y` yields the inverse
truth value.

Thus, the check for identity is the same as checking for the equality of the IDs of the objects. That is,

``````a is b
``````

is the same as:

``````id(a) == id(b)
``````

where `id` is the builtin function that returns an integer that “is guaranteed to be unique among simultaneously existing objects” (see `help(id)`) and where `a` and `b` are any arbitrary objects.

## Other Usage Directions

You should use these comparisons for their semantics. Use `is` to check identity and `==` to check equality.

So in general, we use `is` to check for identity. This is usually useful when we are checking for an object that should only exist once in memory, referred to as a “singleton” in the documentation.

Use cases for `is` include:

• `None`
• enum values (when using Enums from the enum module)
• usually modules
• usually class objects resulting from class definitions
• usually function objects resulting from function definitions
• anything else that should only exist once in memory (all singletons, generally)
• a specific object that you want by identity

Usual use cases for `==` include:

• numbers, including integers
• strings
• lists
• sets
• dictionaries
• custom mutable objects
• other builtin immutable objects, in most cases

The general use case, again, for `==`, is the object you want may not be the same object, instead it may be an equivalent one

### PEP 8 directions

PEP 8, the official Python style guide for the standard library also mentions two use-cases for `is`:

Comparisons to singletons like `None` should always be done with `is` or
`is not`, never the equality operators.

Also, beware of writing `if x` when you really mean `if x is not None`
e.g. when testing whether a variable or argument that defaults to `None`
was set to some other value. The other value might have a type (such
as a container) that could be false in a boolean context!

## Inferring equality from identity

If `is` is true, equality can usually be inferred – logically, if an object is itself, then it should test as equivalent to itself.

In most cases this logic is true, but it relies on the implementation of the `__eq__` special method. As the docs say,

The default behavior for equality comparison (`==` and `!=`) is based on
the identity of the objects. Hence, equality comparison of instances
with the same identity results in equality, and equality comparison of
instances with different identities results in inequality. A
motivation for this default behavior is the desire that all objects
should be reflexive (i.e. x is y implies x == y).

and in the interests of consistency, recommends:

Equality comparison should be reflexive. In other words, identical
objects should compare equal:

`x is y` implies `x == y`

We can see that this is the default behavior for custom objects:

``````>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)
``````

The contrapositive is also usually true – if somethings test as not equal, you can usually infer that they are not the same object.

Since tests for equality can be customized, this inference does not always hold true for all types.

### An exception

A notable exception is `nan` – it always tests as not equal to itself:

``````>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False
``````

Checking for identity can be much a much quicker check than checking for equality (which might require recursively checking members).

But it cannot be substituted for equality where you may find more than one object as equivalent.

Note that comparing equality of lists and tuples will assume that identity of objects are equal (because this is a fast check). This can create contradictions if the logic is inconsistent – as it is for `nan`:

``````>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True
``````

## A Cautionary Tale:

The question is attempting to use `is` to compare integers. You shouldn’t assume that an instance of an integer is the same instance as one obtained by another reference. This story explains why.

A commenter had code that relied on the fact that small integers (-5 to 256 inclusive) are singletons in Python, instead of checking for equality.

Wow, this can lead to some insidious bugs. I had some code that checked if a is b, which worked as I wanted because a and b are typically small numbers. The bug only happened today, after six months in production, because a and b were finally large enough to not be cached. – gwg

It worked in development. It may have passed some unittests.

And it worked in production – until the code checked for an integer larger than 256, at which point it failed in production.

This is a production failure that could have been caught in code review or possibly with a style-checker.

Let me emphasize: do not use `is` to compare integers.

`==` determines if the values are equal, while `is` determines if they are the exact same object.

# What’s the difference between `is` and `==`?

`==` and `is` are different comparison! As others already said:

• `==` compares the values of the objects.
• `is` compares the references of the objects.

In Python names refer to objects, for example in this case `value1` and `value2` refer to an `int` instance storing the value `1000`:

``````value1 = 1000
value2 = value1
``````

Because `value2` refers to the same object `is` and `==` will give `True`:

``````>>> value1 == value2
True
>>> value1 is value2
True
``````

In the following example the names `value1` and `value2` refer to different `int` instances, even if both store the same integer:

``````>>> value1 = 1000
>>> value2 = 1000
``````

Because the same value (integer) is stored `==` will be `True`, that’s why it’s often called “value comparison”. However `is` will return `False` because these are different objects:

``````>>> value1 == value2
True
>>> value1 is value2
False
``````

## When to use which?

Generally `is` is a much faster comparison. That’s why CPython caches (or maybe reuses would be the better term) certain objects like small integers, some strings, etc. But this should be treated as implementation detail that could (even if unlikely) change at any point without warning.

You should only use `is` if you:

• want to check if two objects are really the same object (not just the same “value”). One example can be if you use a singleton object as constant.

• want to compare a value to a Python constant. The constants in Python are:

• `None`
• `True`1
• `False`1
• `NotImplemented`
• `Ellipsis`
• `__debug__`
• classes (for example `int is int` or `int is float`)
• there could be additional constants in built-in modules or 3rd party modules. For example `np.ma.masked` from the NumPy module)

In every other case you should use `==` to check for equality.

## Can I customize the behavior?

There is some aspect to `==` that hasn’t been mentioned already in the other answers: It’s part of Pythons “Data model”. That means its behavior can be customized using the `__eq__` method. For example:

``````class MyClass(object):
def __init__(self, val):
self._value = val
def __eq__(self, other):
print('__eq__ method called')
try:
return self._value == other._value
except AttributeError:
raise TypeError('Cannot compare {0} to objects of type {1}'
.format(type(self), type(other)))
``````

This is just an artificial example to illustrate that the method is really called:

``````>>> MyClass(10) == MyClass(10)
__eq__ method called
True
``````

Note that by default (if no other implementation of `__eq__` can be found in the class or the superclasses) `__eq__` uses `is`:

``````class AClass(object):
def __init__(self, value):
self._value = value
>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a
``````

So it’s actually important to implement `__eq__` if you want “more” than just reference-comparison for custom classes!

On the other hand you cannot customize `is` checks. It will always compare just if you have the same reference.

## Will these comparisons always return a boolean?

Because `__eq__` can be re-implemented or overridden, it’s not limited to return `True` or `False`. It could return anything (but in most cases it should return a boolean!).

For example with NumPy arrays the `==` will return an array:

``````>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)
``````

But `is` checks will always return `True` or `False`!

1 As Aaron Hall mentioned in the comments:

Generally you shouldn’t do any `is True` or `is False` checks because one normally uses these “checks” in a context that implicitly converts the condition to a boolean (for example in an `if` statement). So doing the `is True` comparison and the implicit boolean cast is doing more work than just doing the boolean cast – and you limit yourself to booleans (which isn’t considered pythonic).

Like PEP8 mentions:

Don’t compare boolean values to `True` or `False` using `==`.

``````Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:
``````

They are completely different. `is` checks for object identity, while `==` checks for equality (a notion that depends on the two operands’ types).

It is only a lucky coincidence that “`is`” seems to work correctly with small integers (e.g. 5 == 4+1). That is because CPython optimizes the storage of integers in the range (-5 to 256) by making them singletons. This behavior is totally implementation-dependent and not guaranteed to be preserved under all manner of minor transformative operations.

For example, Python 3.5 also makes short strings singletons, but slicing them disrupts this behavior:

``````>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False
``````

https://docs.python.org/library/stdtypes.html#comparisons

`is` tests for identity
`==` tests for equality

Each (small) integer value is mapped to a single value, so every 3 is identical and equal. This is an implementation detail, not part of the language spec though

Your answer is correct. The `is` operator compares the identity of two objects. The `==` operator compares the values of two objects.
You can control comparison behaviour of object values by defining a `__cmp__` method or a rich comparison method like `__eq__`.