is vs ==

RoadmapsPython Backend

Overview

The `==` operator compares the VALUES of two objects (equality), while the `is` operator compares the MEMORY ADDRESSES of two objects (identity). Two distinct objects can have the exact same value (`==` is True), but because they live in different places in memory, they are not the same object (`is` is False). Think of `==` as asking 'Do these two houses look identical?' and `is` as asking 'Are these two addresses pointing to the exact same house?'. In Python, `is` checks if `id(a) == id(b)`.

Mixing up `is` and `==` causes subtle bugs. Use `==` when you want to know if the data matches. Only use `is` when you need to know if two variables refer to the exact same object in memory (most commonly, checking `is None`).

Where used: FastAPI, Pydantic, Django

Why learn this

Code walkthrough

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

Focus: print(a is b)

Aha moment

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

x = [1, 2, 3]
y = [1, 2, 3]
print(x is y)

Prediction: What will these two prints output?

Common guess: True, True

Even though `a` and `b` have identical contents (so `a == b` is True), lists are mutable objects. Python creates a brand new list in memory every time `[1, 2, 3]` is evaluated. Therefore `x` and `y` point to different memory addresses, and `x is y` is False.

Common mistakes

Glossary

identity
The unique memory address or location of an object in a computer, confirming it is the exact same object. Example: `id(a) == id(b)` is the underlying check that `a is b` performs.
singletons
Objects or classes that are designed so that only one unique instance of them can ever exist in a program. Example: `None`, `True`, and `False` are singletons in Python — `x is None` is always the right check.

Recall questions

Understanding checks

What will the following code output?

`True` followed by `False`

`a` and `b` have the same values, so `a == b` is `True`. However, they are two distinct list objects in memory, so `a is b` evaluates to `False`.

Why is it recommended to use `x is None` instead of `x == None`?

Because `is` guarantees an identity check, preventing bugs if an object overrides `==` to behave unexpectedly.

Using `== None` triggers the `__eq__` method, which some libraries override to return custom objects instead of a simple boolean. `is None` directly compares memory addresses and cannot be overridden.

Practice tasks

Fix the singleton comparison

The `process_data` function currently uses `==` to check if the result is `None`. This works most of the time but can be unsafe. Modify the function to use the correct operator for checking identity against singletons like `None`.

Challenge

Safe None Checking

You are writing a database connector. Write a function `process_record(record)` that takes a record (which could be a dictionary or `None`). If `record` is exactly `None`, return the string 'No data'. Otherwise, return the string 'Processing'. You must use the safest comparison operator for `None`.

Continue learning

Previous: Variables as references

Next: Mutable vs immutable types

Next: Shallow vs deep copy

Return to Python Backend Roadmap