Is there a difference between "==" and "is"?
Asked Answered
A

13

628

My Google-fu has failed me.

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?

Avruch answered 25/9, 2008 at 12:27 Comment(0)
U
1155

is will return True if two variables point to the same object (in memory), == 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.

Urethritis answered 25/9, 2008 at 12:32 Comment(6)
I found that: echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foo output: False True False.Tantamount
You lost me with the b = a[:] slice operator list copy part, so I've edited your answer to have a comment there. Looks like I just reached the threshold to not have to have my edits reviewed before they apply, so hopefully that's cool with you. Regardless, here's a useful reference for how to copy lists that I came across and had to reference to figure out what you were doing: https://mcmap.net/q/37521/-how-do-i-clone-a-list-so-that-it-doesn-39-t-change-unexpectedly-after-assignmentBurp
Another way to demonstrate the difference is by comparing objects of different types, which can, of course, never be the same object but still compare equal when using ==. So 5.0 for example, is a floating point value, while 5 is an integer. But 5.0 == 5 will still return True because they represent the same value. In terms of performance and duck-typing, is is always tested by the interpreter by comparing the operand's memory adresses, while with == it is up to the object to decide if it defines itself as equal to something else.Childish
1000 is 10**3 evaluates to True in Python 3.7 since 10**3 is type int. But 1000 is 1e3 evaluates to False since 1e3 is type float.Elsyelton
@AhmedFasih Whether or not 1000 is 10**3 is true is implementation dependent, and depends on the compiler pre-evaluating the expression 10**3. x=10; 1000 is x**3 evaluates to False.Audacity
Just a side note. Python 3.8 and onwards return a SyntaxWarning when comparing literal like 1000 is 10**3: SyntaxWarning: "is" with a literal. Did you mean "=="?Pushup
S
403

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.

Superfluid answered 6/7, 2009 at 6:22 Comment(3)
With regards to the first example of a=500 and b=500, just wanted to point out that if you set a and b to an interger between [-5, 256], a is b actually returns True. More information here: https://mcmap.net/q/37105/-quot-is-quot-operator-behaves-unexpectedly-with-integers/7571052Finitude
@AsheKetchum, yes, note that I wrote "It turns out the reference implementation of Python caches integer objects in the range -5..256 as singleton instances for performance reasons."Superfluid
Just like to add my two bits here. Use is if you want to check if its the same object (say you have a list of city and route objects each; you could compare the locations, or merely check if its the same city or not - so is is the stronger comparison here). Else if you're only concerned about primitives, usually == will suffice. This is more of a thumb rule that will get violated when the going gets toughAlwyn
I
61

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.

Ingrain answered 5/1, 2018 at 19:33 Comment(9)
"do not use is at all" would be a good rule too. The idiomatic is None being an exception, but that said == None works too...Rattler
@Jean-FrançoisFabre Another exception: The official documentation seems to recommend using is for comparing Enums.Marv
is that mean two custom classes compare, like a = Car("new"), B=Car("new"), if we use a==b, this is equal to a is b, am i right?Postaxial
@UniSize I don't think you are right. Problems: 1. you say a, and B, but then you say a==b (lowercase) and Python is case-sensitive. 2. you don't say whether a and b are supposed to be equivalent, but two instantiations with the same arguments imply that they are equivalent, but not the same objects, thus you would be wrong in your interpretation. Please reread my answer here and let me know what's missing, and be careful and explicit in your response.Ingrain
@AaronHall My appology, first of all, it's a typo. I revised it, a = Car("new"), b=Car("new"), if we use a==b, is this equal to a is b? I understand that "is" is checking whether two objects are in the same memory location, and a==b is the comparison between two objects. Based on the testing, a==b return false, and a is b return false as well. With the same initialization, why will a==b return false?Postaxial
@UniSize That's why I said "think" - The default __eq__ implementation uses is, in which case you would be right. Most custom implementations (and this should be done early in the lifecycle of the object definition, see my PyGotham talk on the subject: youtu.be/iGfggZqXmB0 ) will usually have two separate instantiations with the same arguments for instantiation test as equivalent - in which case you would be wrong. You still didn't say whether a and b are supposed to be equivalent. If you can't find a Q&A that covers this topic, I suggest you write a new question.Ingrain
Worth mentioning that a is b is not necessarily the same as id(a) == id(b), or that a and b can't just be 'anything'. My understanding of is was based on this, and a reputable textbook made the same mistake.Siriasis
As you explain, identity of referred instances ("is"), or referent identity, is the stricter (and strictest?) form of variable equality because it entails (or fully subsumes) value equality ==, while the reverse isn't entailed. It may also be worth mentioning type compatibility here, a notion that yet further elaborates the spectrum of equality distinction. Most generally, it is also the case that type equality (either type(a)==type(b), or type(a) is type(b) since type objects in python are singletons) is entailed by referent equality, and the reverse also not necessarily so.Royalty
Glenn, I think the big takeaway is that while in some cases the test for identity can substitute for a test for equality, and while in some cases this is desirable, in most cases this is undesirable, so we need to be careful to use the correct test for the situation. Additionally, the test for identity of types, while in some cases could be correct, doesn't support substitutability of subclasses for their parent classes.Ingrain
J
48

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

Junco answered 25/9, 2008 at 12:31 Comment(0)
M
26

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

enter image description here

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

enter image description here

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
    • True1
    • False1
    • 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:
Mcgriff answered 19/1, 2018 at 22:21 Comment(8)
I'm going to have to disagree on your assertion to compare "constants" with is - names that point to booleans should be checked with a boolean context - like if __debug__: or if not __debug__:. You should never do if __debug__ is True: or if __debug__ == True: - further, a constant is merely a constant semantic value, not a singleton, therefore checking with is in that case is not semantically correct. I challenge you to find a source to support your assertions - I do not think you will find one.Ingrain
@AaronHall What makes you think that the constants aren't singletons? Note that only None, True, False and __debug__ are what you would call "constant semantic value", because they cannot be reassigned. But all of them are singletons.Mcgriff
Read PEP 8 - Ctrl-F and look for the word, "worse". - If you're unittesting, you'd use self.assertTrueIngrain
@AaronHall In some circumstances you really need the is True or if False check (but yeah, these are pretty rare - but if you do them you can do them using is). That's why even CPython uses them sometimes (for example here or here)Mcgriff
Why is is True worse than == True? Can True is True ever fail? If anything == True is likelier to fail, as __eq__ can be overridden to nonsense, but not is.Siriasis
@Siriasis It's not about failing, it's just about style (this war copied from PEP8- the Python style guide). In the end you probably shouldn't need == True or is True ever (except for special cases or maybe in testing-code).Mcgriff
Disagreed with "never is True"; I've had a few cases where is True is clearly superior in simplicity and readability to its alternatives, and have seen it and is False used in major API production code. This sounds like the "don't exec" advice, which is valid but way inflated out of proportion ("never").Siriasis
@Siriasis Nothing in programming is without exception. It's also not inflated out of proportion... "Never use exec or is True "is the advise to protect readers (including more inexperienced programmers or casual passers-by) from themselves. It's generally assumed that people experienced enough with programming will know when to break the rules.Mcgriff
U
21

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
Unproductive answered 25/9, 2008 at 17:15 Comment(0)
P
12

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

Paleozoology answered 25/9, 2008 at 12:31 Comment(0)
N
7

Your answer is correct. The is operator compares the identity of two objects. The == operator compares the values of two objects.

An object's identity never changes once it has been created; you may think of it as the object's address in memory.

You can control comparison behaviour of object values by defining a __cmp__ method or a rich comparison method like __eq__.

Newport answered 25/9, 2008 at 12:34 Comment(0)
N
5

Have a look at Stack Overflow question Python's “is” operator behaves unexpectedly with integers.

What it mostly boils down to is that "is" checks to see if they are the same object, not just equal to each other (the numbers below 256 are a special case).

Natch answered 6/7, 2009 at 6:20 Comment(0)
A
5

As the other people in this post answer the question in details the difference between == and is for comparing Objects or variables, I would emphasize mainly the comparison between is and == for strings which can give different results and I would urge programmers to carefully use them.

For string comparison, make sure to use == instead of is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Out:

str is hello
str == hello

But in the below example == and is will get different results:

str2 = 'hello sam'
    if (str2 is 'hello sam'):
        print ('str2 is hello sam')
    if (str2 == 'hello sam'):
        print ('str2 == hello sam')

Out:

str2 == hello sam

Conclusion and Analysis:

Use is carefully to compare between strings. Since is for comparing objects and since in Python 3+ every variable such as string interpret as an object, let's see what happened in above paragraphs.

In python there is id function that shows a unique constant of an object during its lifetime. This id is using in back-end of Python interpreter to compare two objects using is keyword.

str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152

But

str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792
Anagoge answered 1/2, 2018 at 15:56 Comment(4)
why does "is"" work like that for strings with spaces?Alanealanine
According to the previous answers: It seems python performs caching on small integer and strings which means that it utilizes the same object reference for 'hello' string occurrences in this code snapshot, while it did not preform caching for 'hello sam' as it is relatively larger than 'hello' (i.e. it manages different references of 'hello sam' string, and that's why the 'is' operator returns false in later example) Please correct me if I am wrongEllison
@AkashGupta sorry for delay response. I just added some more explanation why this thing happened in Python interpreter. I hope it will be helpful.Anagoge
I'm using Python 3.9 and str is 'hello' throws SyntaxWarning: "is" with a literal. Did you mean "=="? This tells us that we need to use == for string comparison which is convenient.Koziol
B
5

In a nutshell, is checks whether two references point to the same object or not.== checks whether two objects have the same value or not.

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 
Boater answered 29/7, 2018 at 20:17 Comment(0)
F
3

As John Feminella said, most of the time you will use == and != because your objective is to compare values. I'd just like to categorise what you would do the rest of the time:

There is one and only one instance of NoneType i.e. None is a singleton. Consequently foo == None and foo is None mean the same. However the is test is faster and the Pythonic convention is to use foo is None.

If you are doing some introspection or mucking about with garbage collection or checking whether your custom-built string interning gadget is working or suchlike, then you probably have a use-case for foo is bar.

True and False are also (now) singletons, but there is no use-case for foo == True and no use case for foo is True.

Fleer answered 6/7, 2009 at 8:50 Comment(1)
For foo=1, foo==True and foo is True are different.Paisley
S
3

Most of them already answered to the point. Just as an additional note (based on my understanding and experimenting but not from a documented source), the statement

== if the objects referred to by the variables are equal

from above answers should be read as

== if the objects referred to by the variables are equal and objects belonging to the same type/class

. I arrived at this conclusion based on the below test:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

Here the contents of the list and tuple are same but the type/class are different.

Saltine answered 7/3, 2018 at 8:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.