Comparisons in Python: the difference between “is” and “==”
Tags: python
Published: 2020-01-11 22:11:48

---
title: Comparisons in Python: the difference between “is” and “==”
published: true
description: 
tags: python
canonical_url: https://adriennedomingus.com/blog/comparisons-in-python-the-difference-between-is-and-
---

Comparing one thing to another is constant in programming. But Python has two ways to do this: `==` and `is`. So what’s the difference, anyway?

Let’s give ourselves a class to work with as we see how this all works. A cat, obviously.

```
class Cat():
     def __init__(self, name):
         self.name = name

     def __eq__(self, other):
         return self.name == other.name
```

You’ll notice we’ve defined an `__eq__` method on our `Cat` class: this lets us give a custom definition for what it means for two objects to be equal (docs [here](https://docs.python.org/3/reference/datamodel.html#object.__eq__)). In this case, we’ve said that if two cats have the same name, they equal each other.

Ok, let’s instantiate some instances of cats, Mena and Llewyn, and another cat, also named Mena, but not my cat Mena, and compare them:
![My cat Mena on the left, my brother's cat Llewyn on the right](https://thepracticaldev.s3.amazonaws.com/i/kti8qvlf6w3guyy3ngqy.jpg)
_(That's my cat Mena on the left, and my brother's cat Llewyn on the right)_

```
>>> mena = Cat("Mena")
>>> llewyn = Cat("Llewyn")
>>> another_cat_named_mena = Cat("Mena")

>>> mena == llewyn
False
>>> mena == another_cat_named_mena
True
```

This aligns with what we’d expect, given how we defined equality on `Cat` above: `mena` and `another_cat_named_mena` have the same name, so we’ve decided they’re equal. But they’re not actually the same cat. Let’s prove it! Every object in Python is assigned a unique id, which actually references its location in memory, though that’s not important for our purposes:

```
>>> id(mena)
4427700624
>>> id(llewyn)
4427700880
>>> id(another_cat_named_mena)
4427701008
```

This confirms that `mena` and `another_cat_named_mena` are actually different cats. So what if we want to know whether two objects we have are actually the same instance of an object, even with an overridden `__eq__` method ? That’s where is comes in! Let’s take a look:

```
>>> mena == another_cat_named_mena
True  # we already knew this!
>> mena is another_cat_named_mena
False
```

`is` under the hood actually compares the id of the object, and only returns `True` if they’re the same instance. While we can customize how `==` is evaluated, Python does not allow for is to be customized. 

## Built-ins
When it comes to built-ins, including types and constants, even when we instantiate two different variables with the same value, they actually refer to the same object in memory:

```
>>> a = 1
>>> b = 1
>>> id(a)
140563925985544
>>> id(b)
140563925985544
>>> a == b
True
>>> a is b
True
```

Python assumes that these values will be used frequently enough, that they cache them to store memory. This is where it gets interesting though! Python only does this up to a point. 256, to be exact. After that, things aren’t cached, and so they’re equal, but they don’t refer to the same instance:

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

## Summary
In short: `==` will compare the value of two things, while is compares whether two things are actually the exact same instance, but be aware of how this might lead to unexpected results when it comes to built-ins!