Variables as references

RoadmapsPython Backend

Overview

Every Python object has a unique identity — its location in memory — which you read with id(). The `is` operator compares identity (are these the same object?), while `==` compares value (do they have equal contents?). Two separate lists with the same items are == but not `is`, because they are distinct objects; only a name assigned from another (c = a) shares identity. Think of id() as a house's street address and == as two houses having identical furniture: the same address is literally the same house, identical furniture is not.

Confusing `is` with `==` causes real bugs. The safe rule: use `is` only for None, True, and False, and use `==` for comparing values. Checking values with `is` (e.g. x is 1000) can pass or fail unpredictably because only some objects are cached.

Where used: None checks in API handlers, Pydantic validators, debugging shared references

Why learn this

Code walkthrough

a = {'id': 1}
b = {'id': 1}
c = a
print(a == b)
print(a is b)
print(a is c)

Focus: a and b are equal (==) but not identical (is); only c, assigned from a, is the same object.

Aha moment

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

big = 1000
print(big is int('1000'))

Prediction: Both lines compare equal integers with `is`. What does each print?

Common guess: True for both

CPython caches small integers (-5 to 256), so 256 is always that one cached object (is is True). 1000 is outside the cache, and int('1000') builds a fresh object at runtime, so it is a different object (is is False). Use == for values; reserve is for None/True/False.

Common mistakes

Glossary

cached
Storing frequently used data in a temporary, fast-access memory area so it doesn't have to be recreated every time. e.g. CPython caches small integers so `a = 5; b = 5; a is b` is `True`.
CPython
The standard, original, and most widely used version of the Python programming language, written in C. Example: `python script.py`.

Recall questions

Understanding checks

What will be printed when this script is run?

True, False, True

`a == b` is True because their contents match. `a is b` is False because `b` is a freshly created list with a different memory address. `a is c` is True because `c` is assigned directly from `a`, so they reference the exact same object in memory.

A developer is writing a validator that ensures a users balance matches exactly 1000. Identify the bug.

The function uses `is` to check for equality of the value 1000.

Because CPython only caches small integers, using `is` to compare values like 1000 can fail unpredictably depending on how the object was created in memory. To compare values, you must use `==`. `is` should only be used for `None`, `True`, and `False`.

Practice tasks

Fixing the Identity Check

The function below incorrectly uses `is` to check if a users input matches a specific integer, and uses `==` to check if a result is `None`. Modify the code to use the correct operators for value comparison and identity checking.

Challenge

A correct None check

Write get_or_default(value, default) that returns default ONLY when value is None — not when value is 0, '', or an empty list. Use the correct operator, then print three calls to prove 0 and '' are kept.

Continue learning

Previous: Mutable vs immutable types

Next: Shallow vs deep copy

Return to Python Backend Roadmap