Concepts / Mutable vs. Immutable Types

Mutable vs. Immutable Types

Identity (is) checks whether two variables refer to the same object in memory; equivalence (==) checks whether two objects have the same value.

  • Programming
Interactive lab

Try it: Names and Objects

How Python variables are names bound to objects: assignment never copies, mutating a list is seen through every name that points at it, and ints are replaced rather than changed.

How it works

  1. name = object binds a name; b = a makes b point at the same object.
  2. Mutating a list (append, +=) changes the one shared object.
  3. a = a + [x] and y = y + 1 create NEW objects and re-point one name.
  4. Passing a list to a function passes the reference, so the function can change it.

Default run (7 steps): Two names, one list. Every name is a label that points at an object. … Printed: [1, 2, 3] / True

Simplified: Six fixed scripts on a tiny heap; you choose the values. Object numbers are illustrative, not real id() values.

Educational simulation

Loading the simulation…

The Backup That Was Not Independent

Imagine creating a list of scores and then assigning it to a variable called backup. You might expect backup to be an independent copy. However, assigning one variable to another creates an alias: both variables refer to the same object. If the list is changed through one variable, the change is visible through the other. The important question is not only whether two variables show the same data, but whether they refer to the same object.

refers torefers toareference[1, 2, 3]object 1breference[1, 2, 3]object 2
How can two variables contain the same value while referring to different objects?

Identity and Equivalence

Identity asks whether two variables refer to the same object in memory. In Python, the is operator tests identity. Value equivalence asks whether two objects contain the same data. The == operator tests equivalence.

These are separate questions. Two list objects can each contain the elements 1, 2, and 3, so they are equivalent even though they are different objects. Conversely, if two variables refer to one identical object, that object necessarily has the same contents when viewed through either variable. Therefore, identity implies equivalence, but equivalence does not necessarily imply identity.

impliesmay still havesame objectidentitysame valueequivalencesame valueequivalencedifferent objectsidentity is not guaranteed
Why does sharing one object guarantee equal values, while equal values do not guarantee one shared object?

Following Two References

The is operator compares references, not merely displayed contents. In the following generated example, a and b are assigned separate list literals. The lists contain the same elements, but Python creates separate list objects for them.

python
Output
True
False

The first result is True because both lists have the same value. The second result is False because a and b refer to different list objects. Writing b = a would produce a different relationship: b would become an alias for the object already referred to by a.

refers torefers todifferent from object 2different from object 1areference[1, 2, 3]object 1a is bFalsebreference[1, 2, 3]object 2
What does each variable point to, and when does is return True?

Immutable Strings and Mutable Lists

Strings are immutable: they cannot be changed after creation. Because an immutable string cannot be altered through one reference, Python can often reuse one string object for multiple variables with the same value. This behavior is called string interning.

Lists are mutable: their contents can be changed. When two list literals with the same elements are created, Python creates separate list objects. This prevents a change made through one independently created list from silently changing another list that only happens to contain the same data.

mutation changes contentsoperation produces a value[1, 2]list[1, 2, 3]same list after mutationtextstringnew valueoriginal string remainsunchanged
What changes when a list is mutated compared with when a string operation produces a value that cannot alter the original string?

Aliasing and Mutation

Tracing One Shared List

Determine what happens when b becomes an alias for a and the list is changed through b.

Create the list: a refers to a list containing 1, 2, and 3.

Create the alias: Assigning b = a makes b refer to the same list object as a. This is not the creation of a separate list.

Check identity: Because both variables refer to the same object, a is b evaluates to True.

Mutate through b: Changing the shared list through b also changes what is visible through a.

Both variables refer to the same changed list, so the mutation is visible through both names.

python
Output
[1, 2, 3, 4]
[1, 2, 3, 4]
True

The two names do not represent two synchronized copies. They are two references to one mutable object. That is why the mutation is visible through both names. If independent data is required, a separate copy must be created explicitly; if shared data is intended, aliasing provides that shared access.

refers torefers tomutation visible through amutation visible through ba[1, 2, 3]shared listone objecta[1, 2, 3, 4]b[1, 2, 3]b[1, 2, 3, 4]
What happens to the other variable when two variables refer to the same mutable list and one variable changes it?

Mistakes with is and ==

  • Using is to ask whether two values are equal

    is checks whether the references point to the same object. It does not ask whether two different objects contain the same data.

    Fix: Use == for value equivalence and is for object identity.

  • Assuming b = a creates a copy

    Assignment creates an alias. Both variables refer to the same object.

    Fix: Create a separate copy explicitly when the original must remain independent.

  • Assuming equal lists must be one object

    Equivalent objects can still be separate objects.

    Fix: Check a is b when identity matters.

  • Expecting mutable lists to behave like immutable strings

    If another variable aliases the same list, both variables expose the changed contents.

    Fix: Trace whether the variables refer to one shared object or to separate list objects.

Practice the Reference Trace

MEDIUM

For each pair below, decide whether the identity test would be True or False, and explain whether the objects are equivalent. Pair A: a = [1, 2]; b = [1, 2] Pair B: a = [1, 2]; b = a Then explain what happens to a if the shared list in Pair B is changed through b.

Hints
  • Ask whether the second assignment creates a new list or another reference to an existing list.
  • Separate the question about contents from the question about object identity.
  • For Pair B, remember that lists are mutable.

What do you think happens?

What do you think these results are: a = [1, 2]; b = a; a is b; a == b?

  • True, True
  • True, False
  • False, True
  • False, False
Reveal answer

Answer: True, True

The assignment b = a creates an alias, so both variables refer to one list object. One shared object is necessarily equivalent to itself.

The Decision to Remember

  1. Identity means that two variables refer to the same object; equivalence means that two objects contain the same data.
  2. Use is to test identity and == to test value equivalence.
  3. Identity implies equivalence, but equivalent objects can be separate objects.
  4. Assigning b = a creates an alias, so a mutation through one variable is visible through the other when the object is mutable.
  5. Strings are immutable and may be reused, while lists are mutable and separately created list literals are separate objects.

Key Takeaways

  • is checks whether two variables refer to one object; == checks whether two objects have the same value.
  • Two separately created lists may be equivalent without being identical.
  • Assigning one variable to another creates an alias rather than an independent copy.
  • Mutating a shared list makes the change visible through every variable that refers to it.
  • Immutable strings can be safely reused more readily than mutable lists.