Mutable vs. Immutable Objects
Variables are references to objects in memory, not the objects themselves.
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.
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?
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.
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.
| Situation | What changes | Effect on another variable referring to the same object |
|---|---|---|
| Change the shared list | The existing list object | The other variable sees the changed list |
| Bind one variable to another object | That variable's reference | The other variable still refers to its existing object |
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.
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.
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
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.
- List the variables involved.
- Determine whether they refer to the same object.
- Identify whether the operation changes the object or changes one variable's reference.
- Predict what each variable will show after the operation.
- 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.