Python Identity Operators

In the last lesson, we learned membership operators. Now let’s learn how Python checks whether two names point to the same object.

After learning Python Membership Operators, we can check whether a collection contains a value. Now let’s see how Python checks whether two variables point to the same object. In this tutorial, we’ll learn about Python identity operators with easy examples.

Let’s Talk About Identity

We already know how to check if two things are equal.

5 == 5 # True

That is equality. Are these two values the same? Yes.

But there is another question. Are these two things the same object?

That is a different question. And that is what identity operators are for.

Python has two identity operators:

  • is — checks if two variables point to the same object
  • is not — checks if two variables do not point to the same object

Let’s understand this properly.

What Does “Same Object” Mean?

In Python, everything is an object. Every value we create lives somewhere in memory.

When we assign a value to a variable, the variable points to that object in memory.

Sometimes, two variables point to the same object. Sometimes they point to two different objects that happen to have the same value.

Let’s see.

a = [1, 2, 3]
b = [1, 2, 3]

Here, a and b have the same value. Both are lists with 1, 2, 3.

But are they the same object? No. They are two separate lists. Two separate objects in memory. They just happen to contain the same things.

print(a == b) # True (same value)
print(a is b) # False (different objects)

See the difference?

  • == asks: do they have the same value?
  • is asks: are they the exact same object?

A Real-Life Analogy

Imagine two people. Both are named Alex Smith. Both are 25 years old. Both live in London.

Are they equal? In terms of data, yes. Same name, same age, same city.

But are they the same person? No. They are two different people.

== would say True. is would say False.

Now imagine one person. We point at them with our left hand. Our friend points at them with their right hand.

Are we pointing at the same person? Yes. Same person. Two different pointers.

is would say True.

That is identity.

Python is Operator

So what does is do? It checks if two variables refer to the same object.

a = [1, 2, 3]
b = a
print(a is b) # True

Here, b = a does not copy the list. It makes b point to the same list as a.

So a and b are the same object. is gives True.

Now let’s change a:

a = [1, 2, 3]
b = a
a.append(4)
print(b) # [1, 2, 3, 4]

See? We changed a, and b changed too. Because they are the same object.

Python is not Operator

So what does is not do? It’s the opposite. It checks if two variables do not refer to the same object.

a = [1, 2, 3]
b = [1, 2, 3]
print(a is not b) # True

Because a and b are different objects.

When to Use is?

Most of the time, we should use ==. Because we care about the value, not the identity.

But there is one important case where we must use is: when comparing with None.

x = None
if x is None:
print("x is None")

Why is and not ==? Because None is a singleton. There is only one None object in Python. So identity works perfectly.

And it is faster. And it is the recommended style.

So the rule is:

  • Use == for comparing values
  • Use is for comparing with None
  • Use is when we really need to check if two variables point to the same object

Common Mistakes with Python Identity Operators

Mistake 1: Using is Instead of == for Numbers

Here’s a mistake we all make. We write a = 1000 and b = 1000. Then we check a is b. And sometimes it’s False.

a = 1000
b = 1000
print(a is b) # Might be False!
print(a == b) # True

Why might a is b be False? Because Python might create two different objects for 1000. Or it might reuse the same object. It depends on the implementation. So we should never rely on is for numbers.

So what do we do? We use == for value comparison.

Mistake 2: Using is with Strings

Let’s say we write a = "hello" and b = "hello". Then we check a is b.

a = "hello"
b = "hello"
print(a is b) # Might be True or False
print(a == b) # True

Why might it be either? Because Python may reuse small strings, but it is not guaranteed. So we should not rely on is for strings.

So what do we do? We use ==.

Mistake 3: Using is with Lists

Here’s one. We write a = [1, 2, 3] and b = [1, 2, 3]. Then we check a is b.

a = [1, 2, 3]
b = [1, 2, 3]
print(a is b) # False
print(a == b) # True

Why? Because a and b are two different lists. Same contents, different objects.

If we want to check if two lists have the same content, we use ==. If we want to check if they are the same list, we use is.

Mistake 4: Forgetting That b = a Does Not Copy

Let’s say we write b = a and then change b. What happens to a?

a = [1, 2, 3]
b = a
b.append(4)
print(a) # [1, 2, 3, 4]

a changed too. Why? Because b = a does not make a copy. It just makes b point to the same list.

Many beginners think b = a makes a copy. It does not.

So what do we do? If we want a copy, we use b = a.copy() or b = a[:].

a = [1, 2, 3]
b = a.copy()
b.append(4)
print(a) # [1, 2, 3]
print(b) # [1, 2, 3, 4]

Now a does not change. Because b is a separate copy.

A Complete Example

Let’s see identity in action.

list1 = [1, 2, 3]
list2 = [1, 2, 3]
list3 = list1
print("list1 == list2:", list1 == list2) # True
print("list1 is list2:", list1 is list2) # False
print("list1 == list3:", list1 == list3) # True
print("list1 is list3:", list1 is list3) # True
list1.append(4)
print("After changing list1:")
print("list1:", list1) # [1, 2, 3, 4]
print("list2:", list2) # [1, 2, 3]
print("list3:", list3) # [1, 2, 3, 4]

Output

list1 == list2: True
list1 is list2: False
list1 == list3: True
list1 is list3: True
After changing list1:
list1: [1, 2, 3, 4]
list2: [1, 2, 3]
list3: [1, 2, 3, 4]

See how list3 changed because it points to the same object as list1? And list2 did not change because it is a separate object.

That is identity.

Next, we will learn about Bitwise Operators so we can work with the binary bits inside integers.