The is and == operators in Python
Beware of confusion between is and == operators in Python
Object identity and numeric equality are not the same.
One thing to consider when comparing numbers or objects using the operators is / == don’t even think they are interchangeable, you will run into problems :)
I found out about it the hard way when writing a little function to check whether a number was a perfect square.
The code in question
import math
def is_square(n):
if n <= 0:
return False
nx = int(round(math.sqrt(n)))
nxsum = nx*nx
if nxsum == n:
return True
else:
return False
It’s not particularly nice, but it will serve us as a good example why you should always be aware that == and is are not the same operator in Python nor can they be used interchangeably. It might work sometimes, but then you’re just lucky, don’t do it.
So, I was trying to write my final if statement checking if number n was indeed a perfect square like this
if nxsum is n:
return True
And I wondered why it wasn’t working. I checked it against randomly created perfect squares, one of them was 88900304 which I will use as example for the rest of this post.
So I was testing is_square(88900304) and upon the errors I encounterd I proceeded to verify in the Python shell what the variables nx and nxsum would hold. I ended up with the somewhat baffling conclusion you can see below:
>>> n
807241744
# nx being the square root of n
>>> nx
28412
# and nxsum should be equal to n
>>> nxsum = nx * nx
>>> nxsum
807241744
nxsum and n look like the same number, my code is correct I thought. I found a perfect square and my function should just return True. But instead it was returning False! When writing that if clause I was completely oblivious to the implications and thought is would just be a somewhat more pythonic way to write ==. Big mistake! They are not the same operator. == is used for numeric equality and is is used to compare object identity.
This means that while both nxsum and n do represent the same numeric value (807241744) they are different objects.
>>> nxsum is n
False
>>> nxsum == n
True
It all makes sense when you check the objects using id()
>>> id(n)
88900864
>>> id(nxsum)
88900320
So while they hold the same numeric value, n is not nxsum
in a pythonic sense, as they are different objects in memory.