is and == in Python: What's the Difference?

In Python, you can encounter both the `==` operator and `is` when comparing values.

Consider a simple example:

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

print(a == b)
print(a is b)

Result:

True
False

The lists `a` and `b` contain the same values, so the expression `a == b` returns `True`. At the same time, the lists themselves were created separately. They are two different objects, so `a is b` returns `False`.

If we modify the example as follows:

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

print(a == b)
print(a is b)

then the result will be different:

True
True

In this case, no new list was created for `b`. The variable `b` was assigned a reference to the same object that `a` already refers to.

You can also check this using the `id()` function:

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

print(id(a))
print(id(b))

The `id` values will be the same.

== answers the question: “Do the objects have the same values?”

is answers the question: “Is this the same object?”

When to Use ==

In most ordinary comparisons, the `==` operator is the one you need.

For example:

age = 25

if age == 25:
    print("Age matches")

The same applies to strings:

name = "Ian"

if name == "Ian":
    print("Name matches")

And to collections:

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

if a == b:
    print("Lists are equal")

Here, we are interested in the contents of the objects, not where exactly they are located in memory.

When to Use is

`is` makes sense in cases where you need to check object identity.

The most common example is `None`:

result = None

if result is None:
    print("No result")

For the opposite check, `is not` is used:

if result is not None:
    print(result)

This is the form that is usually used in Python code instead of:

if result == None:
    ...

Why is Sometimes Works with Numbers and Strings

Sometimes you may encounter code like this:

a = 10
b = 10

print(a is b)

And get:

True

After this, it may seem that `is` is perfectly suitable for comparing numbers.

However, you should not rely on this behavior. Python may reuse some objects that have already been created. This applies, for example, to some integers and strings.

Therefore, writing:

if number is 10:
    ...

is incorrect.

You should use:

if number == 10:
    ...

The same applies to strings:

if status == "active":
    ...

and not:

if status is "active":
    ...

The behavior of a program should not depend on whether Python reused an existing object or created a new one.

Ian L. Dolganov
Ian L. Dolganov
Junior Python Developer

My academic interests focus on Python development, software engineering, backend development, and modern approaches to designing and developing reliable software systems.