← Back to Python

is vs ==

PythonEntrypython

The Question

What is the difference between 'is' and '==' in Python?

What a Strong Answer Covers

  • is = identity (id())
  • "== = equality (__eq__)
  • "id() not hash()
  • "is for None

Senior-Level Answer

In Python, `is` and `==` are fundamentally different operations that are often confused because they coincidentally produce the same result in common cases.

`==` calls `__eq__()` on the left-hand operand. It tests **value equality** — whether two objects represent the same value according to the class's definition. For built-in types, this is intuitive: `[1, 2] == [1, 2]` is `True` even though they are distinct list objects.

`is` tests **object identity** — whether two names refer to the exact same object in memory. It is equivalent to `id(a) == id(b)`. It does NOT call `__eq__`. No overriding is possible.

The dangerous trap is CPython's optimization of caching small integers (typically -5 to 256) and interned string literals. Because these objects are cached and reused, `is` appears to work:

```python a = 256 b = 256 a is b # True — same cached object

a = 257 b = 257 a is b # False in most contexts — different objects ```

Similarly with strings:

```python 'hello' is 'hello' # True — interned 'hello world' is 'hello world' # May be False ```

This behavior is a CPython implementation detail, not guaranteed by the language specification. Code relying on it is not portable across Python implementations (PyPy, Jython) and can break with dynamic string construction.

**Correct usage of `is`:** Comparing to singletons — `None`, `True`, `False`. PEP 8 explicitly recommends `if x is None` over `if x == None`. This is both more semantically accurate (you mean identity) and safe because `==` can be overridden (`__eq__` might do something unexpected on a custom class).

**When `==` is what you want:** Virtually always, when comparing values — numbers, strings, lists, custom objects. Define `__eq__` on your classes to control equality semantics.

A common bug pattern: checking `if result is True` when a function returns a truthy non-True value (e.g., 1 or a non-empty list). Use `if result == True` or better `if result`.

Key Differences

Aspectis==
What it testsObject identityValue equality
Mechanismid(a) == id(b)Calls a.__eq__(b)
Can be overriddenNoYes (__eq__)
Use with NoneCorrect (is None)Risky (__eq__ can lie)
CPython small int trapYes (appears to work)Not affected
PEP 8 guidanceOnly for singletonsDefault for value comparison

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Correctly explains identity vs value equality and knows to use 'is None' instead of '== None', with the small int caching caveat.

3/3 — Strong Answer

Covers identity vs value equality, explains id() equivalence, names the CPython caching behavior and why it's unreliable, explains PEP 8's recommendation, and describes __eq__ overriding risk.

Common Mistakes

  • Using 'is' to compare strings or numbers in production code relying on interning
  • Not knowing that == calls __eq__ and can be overridden, making 'is None' safer
  • Saying 'is' is faster therefore preferred — correctness trumps micro-optimization
  • Forgetting that the small int cache range (-5 to 256) is CPython-specific

Follow-Up Questions

  • Why does PEP 8 say 'use is None' instead of '== None'? — A class can override __eq__ and make == None return True even when the object isn't None. 'is' is unoverridable.
  • What does id() return and how does it relate to 'is'? — id() returns the memory address of the object in CPython. 'a is b' is exactly 'id(a) == id(b)'.
  • If I define __eq__ but not __hash__, what happens? — Python sets __hash__ to None, making the object unhashable (can't be used in sets or as dict keys). They must be consistent.
  • How would you check if two variables point to the same list versus containing the same elements? — Same object: 'a is b'. Same contents: 'a == b'. Demonstrate with id() to make it concrete.

Related Questions

  • GIL — What It Is and What It Protects
  • ThreadPoolExecutor & ProcessPoolExecutor
  • Decorators — Under the Hood
  • Generators & yield
  • Context Managers

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout