Concepts / Mutable vs. Immutable Objects

Mutable vs. Immutable Objects

Variables are references to objects in memory, not the objects themselves.

  • 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…

One List, Two Names

A variable does not contain the object itself. It refers to an object in memory. This distinction matters when more than one variable refers to the same list: a change made through one variable changes the shared list, so the change is visible through the other variable as well.

shoplistvariablelist objectshared objectmylistvariablerefers torefers to
What does the object relationship look like when two variables refer to the same list rather than referring to separate lists?

Tracing a Shared Reference

Imagine that two variables refer to one list object. The variables are two ways to reach that same object; they are not two separate lists. If the list is changed through one variable, the object itself changes. Because the other variable still refers to that object, it shows the changed list too.

What do you think happens?

Two variables refer to the same list. If the list is changed through the first variable, what should you expect through the second variable?

  • The second variable shows the changed shared list

  • The second variable automatically receives a separate unchanged list

  • The second variable stops referring to an object

Reveal answer
Answer:

The second variable shows the changed shared list.

Multiple variables can point to the same object, and changes through one variable affect all variables pointing to that object.

shoplistlist objectlistoriginal contentsshoplistlist objectlistchanged contentsmylistsame list objectmylistsame list objectrefers torefers torefers torefers to
What happens to every variable pointing to a list when that shared list is changed in place?

Mutation and Rebinding

The central question is whether an operation changes an existing object or changes a variable's reference to an object. When multiple variables refer to one list, changing that shared list affects all of those variables. By contrast, assigning a variable to another object changes which object that variable refers to; it does not make the variables identical containers. Thinking in terms of object binding helps explain why unexpected modifications can appear in multiple places.

SituationWhat changesEffect on another variable referring to the same object
Change the shared listThe existing list objectThe other variable sees the changed list
Bind one variable to another objectThat variable's referenceThe other variable still refers to its existing object

The important distinction is between changing an object and changing a variable's reference.

shared listexisting objectall referencessee changed objectone variablereference changesother objectnew targetother variablekeeps its targetchanges visible throughrefers tostill refers to
What is the difference between changing an existing shared list and changing which object one variable refers to?

Making an Independent List

When you need a separate list object, use full slice notation. The source pack gives the form mylist = shoplist[:]. This creates an independent copy rather than another variable pointing to the same list object. After the copy, changes to one list do not represent changes made to the other list object.

shoplistoriginal variableoriginal listone list objectmylistcopied variablecopied listindependent list objectrefers torefers tocreated by full slice
How does full slice notation create a new list object, and how do the original and copied lists relate afterward?
Worked example

Choosing Between an Alias and a Copy

You have a list called shoplist and want mylist to be independent. Which relationship should you create?

  1. 1
    Identify the risk

    If both variables point to one list object, a change through either variable affects the shared object and is visible through both variables.

  2. 2
    Use full slice notation

    Write mylist = shoplist[:]. The full slice notation creates an independent copy of the list.

  3. 3
    Predict later changes

    A later change to one list object is not a change made to the other list object, because the variables refer to independent list objects.

Result

Use mylist = shoplist[:] when the goal is an independent copy rather than another reference to the same list.

Aliasing or Independence

A useful prediction routine has three steps. First, identify every variable that may refer to the same object. Second, decide whether the next operation changes that object or changes one variable's reference. Third, predict what each variable will show afterward. If the variables share one list, expect a change through one variable to appear through the others. If full slice notation created an independent copy, treat the two list objects separately.

variable Asame list targetone listshared objectvariable Aoriginal list targetoriginal listseparate objectvariable Bsame list targetvariable Bcopied list targetcopied listseparate objectrefers torefers torefers torefers to
How can you predict whether changing one variable will also change the value seen through another variable?

Mistakes with Shared Lists

  • Common mistake

    Assuming that two variable names mean there are two list objects.

    What it looks like

    Two variables can point to the same object.

    Why it fails

    Variables are references to objects, not the objects themselves.

    Do this instead

    Trace which object each variable refers to before predicting the result of a change.

  • Common mistake

    Expecting a change through one variable to remain private to that variable.

    What it looks like

    A shared list is changed through one variable.

    Why it fails

    The change affects the shared object, so every variable pointing to it sees the change.

    Do this instead

    Use full slice notation when an independent list copy is required.

  • Common mistake

    Treating an independent copy as another reference to the original list.

    What it looks like
    mylist = shoplist[:]
    Why it fails

    Full slice notation is used to create an independent copy.

    Do this instead

    Recognize that the original and copied variables refer to separate list objects.

Practice the Prediction

MEDIUM

For each situation, predict whether a change made through one variable will also be visible through another variable. Situation A: both variables refer to the same list object. Situation B: the second variable was created with full slice notation from the first list. Explain your prediction using the words object, reference, and independent copy.

Hints
  • Start by asking whether the variables refer to one list object or to separate list objects.
  • A shared object gives changes through one variable a wider effect.
  • Full slice notation is the source-pack method for creating an independent list copy.
  1. 1
    List the variables involved.
  2. 2
    Determine whether they refer to the same object.
  3. 3
    Identify whether the operation changes the object or changes one variable's reference.
  4. 4
    Predict what each variable will show after the operation.
  5. 5
    If independence is required, use full slice notation to create a separate list object.

Key Takeaways

  • Variables are references to objects in memory, not the objects themselves.
  • Multiple variables can refer to one list object.
  • A change to a shared list is visible through every variable that refers to that list.
  • Full slice notation, written as mylist = shoplist[:], creates an independent list copy.
  • Tracking object references helps prevent unexpected modifications in multiple places.

More concepts starting with M