Concepts / Mutable vs. Immutable Objects

Mutable vs. Immutable Objects

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

  • Programming

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.

refers torefers toshoplistvariablelist objectshared objectmylistvariable
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.

refers torefers torefers torefers toshoplistlist objectlistoriginal contentsshoplistlist objectlistchanged contentsmylistsame list objectmylistsame list object
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
changes visible throughrefers tostill refers toshared listexisting objectall referencessee changed objectone variablereference changesother objectnew targetother variablekeeps its target
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.

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

Choosing Between an Alias and a Copy

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

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.

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

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.

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.

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

Mistakes with Shared Lists

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

    Variables are references to objects, not the objects themselves.

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

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

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

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

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

    Full slice notation is used to create an independent copy.

    Fix: 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. List the variables involved.
  2. Determine whether they refer to the same object.
  3. Identify whether the operation changes the object or changes one variable's reference.
  4. Predict what each variable will show after the operation.
  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.