# 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.