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.