Get AI summaries of any video or article — Sign up free
Python Quick Tip: The Difference Between "==" and "is" (Equality vs Identity) thumbnail

Python Quick Tip: The Difference Between "==" and "is" (Equality vs Identity)

Corey Schafer·
4 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Use `==` to compare whether two values have the same content, not whether they are the same object.

Briefing

In Python, the difference between `==` and `is` comes down to what gets compared: `==` checks whether two values are equal in content, while `is` checks whether two references point to the exact same object in memory. That distinction matters because two separate objects can be “equal” yet still behave differently when mutated.

A real-world analogy frames the issue using soft drinks at a party. Two people might each have a Pepsi can. With `==`, those cans can be treated as equal because they contain the same drink (same contents). But with `is`, the comparison fails if the cans are different physical objects—two different cans sitting in two different places. The example flips when both people share the same can: if both variables reference the same object, then `is` returns true, and changes made through one reference (like adding a lemon) are reflected through the other.

The code examples make the same point with lists. Two lists, `l1` and `l2`, are first created with different contents (e.g., `l1 = [1,2,3,4,5]` and `l2 = [1,2,4,5]`). Using `==` yields `False` because the values differ. After updating `l2` so both lists contain the same elements, `l1 == l2` becomes `True`—even though the lists are still separate objects in memory. That’s the key nuance: equality can be true without identity.

When the comparison switches to `is`, the result changes. `l1 is l2` is `False` when the lists have identical contents but are distinct objects. Then the script assigns `l2 = l1`, making both names refer to the same list object. At that point, `l1 is l2` becomes `True`, and mutability shows why identity matters: modifying `l1` (changing the first element to `6`) also changes `l2`, because both variables now point to the same underlying list.

To connect `is` to concrete mechanics, the examples use Python’s `id()` function to print object memory addresses. When `l1` and `l2` are the same object, `id(l1)` and `id(l2)` match, and the comparison `id(l1) == id(l2)` returns `True`. The takeaway is practical: use `==` for value comparisons, and use `is` when the goal is to test whether two references are actually the same object.

Cornell Notes

Python’s `==` operator checks value equality, while `is` checks object identity (whether two references point to the same object in memory). Two lists can be equal in contents (`l1 == l2`) yet still fail identity checks (`l1 is l2`) if they are different objects. Assigning `l2 = l1` makes both names refer to the same mutable list, so changes through one reference appear through the other. Using `id()` reveals the underlying mechanism: `is` effectively corresponds to comparing memory addresses. This distinction prevents subtle bugs, especially when working with mutable objects like lists.

Why can `l1 == l2` be `True` while `l1 is l2` is `False`?

Because `==` compares contents, not location. Two separate list objects can hold the same elements (e.g., both become `[1,2,3,4,5]`) and still occupy different memory addresses. In that situation, `l1 == l2` returns `True`, but `l1 is l2` returns `False` since the references are not the same object.

What changes when `l2 = l1` is used instead of creating a separate list with the same values?

`l2 = l1` makes both variables point to the exact same list object in memory. After that assignment, `l1 is l2` becomes `True`. Because lists are mutable, updating one (like setting the first element of `l1` to `6`) also updates what `l2` sees, since there is only one shared list.

How does mutability make identity checks more than a theoretical difference?

With mutable objects like lists, identity determines whether changes propagate. If `l1` and `l2` are different objects, mutating `l1` won’t affect `l2`. If they are the same object (identity via `is`), mutating `l1` changes the shared object, so `l2` reflects the update too.

How does `id()` relate to `is`?

`id()` returns an object’s memory address (or a value representing that identity). When `l1` and `l2` refer to the same object, `id(l1)` and `id(l2)` match. That’s why `l1 is l2` is `True` in the shared-object case, and it can be mirrored by checking `id(l1) == id(l2)`.

In the soft-drink analogy, what does each operator correspond to?

`==` corresponds to “same kind of drink” (same contents/ingredients), so two different Pepsi cans can be considered equal. `is` corresponds to “the exact same can,” meaning both people share one physical object; only then does identity hold.

Review Questions

  1. Give an example of two different objects in Python that would make `==` return `True` but `is` return `False`. Explain why.
  2. What happens to two list variables after `l2 = l1` if you mutate `l1`? Why?
  3. How would you use `id()` to verify whether two references point to the same object?

Key Points

  1. 1

    Use `==` to compare whether two values have the same content, not whether they are the same object.

  2. 2

    Use `is` to check identity: whether two references point to the exact same object in memory.

  3. 3

    Two objects can be equal in value (`l1 == l2`) while still being different objects (`l1 is l2`).

  4. 4

    Assigning `l2 = l1` makes both variables reference the same mutable object, so mutations through one affect the other.

  5. 5

    Python’s `id()` can be used to inspect object identity by comparing memory addresses.

  6. 6

    Identity checks matter most with mutable types like lists, where shared references change behavior under mutation.

Highlights

`==` answers “Are these values equal?” while `is` answers “Are these references the same object?”
Two lists can print as equal yet fail `is` because they live at different memory locations.
After `l2 = l1`, changing `l1` also changes `l2` because both names point to the same mutable list.
`id(l1) == id(l2)` mirrors what `l1 is l2` is checking behind the scenes.

Topics

  • Equality vs Identity
  • Python Operators
  • Mutable Lists
  • Object References
  • Memory Addresses

Mentioned