Understanding Mutability and Immutability
Assignment creates a reference to a list, not a copy. Both variables point to the same object, so modifications through one affect the other.
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
- name = object binds a name; b = a makes b point at the same object.
- Mutating a list (append, +=) changes the one shared object.
- a = a + [x] and y = y + 1 create NEW objects and re-point one name.
- 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.
Loading the simulation…
One List, Two Names
A list can have more than one variable name without being copied. When one list variable is assigned to another, assignment creates a reference to the existing list rather than a separate list. The two variables therefore refer to the same list object. This matters whenever one variable modifies the list: the other variable sees that modification too.
What do you think happens?
Suppose original refers to [1, 2, 3] and alias is assigned from original. If the list is modified through alias, what will original refer to?
Reveal answer
The modified version of the shared list
Assignment creates another reference to the same list object. It does not create a separate copy.
Tracing an Unintended Mutation
Consider the sequence described by the source material: original = [1, 2, 3], followed by alias = original. At this point, original and alias are two names for the same list. If the list is modified through alias, original does not retain an untouched version. It shows the same modification because both names still refer to the shared object.
Copying for Independence
Use copying when two variables must refer to separate lists. The slice notation [:] and the list() constructor create a shallow copy: a new list with the same elements. After copying, modifying one list does not affect the other. This is different from assignment, which gives another variable a reference to the existing list.
| Operation | Result | Effect of modifying one variable |
|---|---|---|
| alias = original | Both variables refer to the same list object | The other variable sees the modification |
| copy = original[:] | copy refers to a new list with the same elements | The original list is not affected |
| copy = list(original) | copy refers to a new list with the same elements | The original list is not affected |
Assignment shares a list; slice notation and list() create a separate shallow list copy.
Choosing a Copy Before Editing
You need to preserve an original list while making changes to another list.
- 1Identify the risk
Assigning a second variable directly from the original would make both variables refer to the same list.
- 2Create independence
Use original[:] or
list(original)to create a new list with the same elements. - 3Modify deliberately
Changes made to the copied list do not affect the original list because the copy is a separate list.
Use a copy when the original must remain available for later use. Modify the original directly only when changing it in place is intentional.
Replacing a Slice
Slice assignment uses the form t[start:end] = sequence. It replaces the elements selected by the slice with the values in the replacement sequence. Because several positions can be replaced at once, slice assignment is useful for bulk list modifications.
In this example, the slice t[1:3] refers to ['b', 'c']. Those two elements are replaced by ['x', 'y']. Because the replacement sequence also contains two elements, the list remains six elements long.
Tracking List Length
The replacement sequence does not have to be the same size as the selected slice. If the replacement is shorter than the slice, the list shrinks. If it is longer, the list grows. If both have the same size, the list keeps its length. This size comparison is the key step when predicting the result of slice assignment.
| Selected slice size | Replacement size | Effect on list length |
|---|---|---|
| Same size | Same size | List length stays the same |
| Larger than replacement | Shorter | List shrinks |
| Smaller than replacement | Longer | List grows |
Compare the number of selected elements with the number of replacement values.
A Longer Replacement
A copied list has 5 elements. A slice containing [30, 40] is replaced by [200, 201, 202]. What happens to the list length?
- 1Count the selected elements
The selected slice contains 2 elements: [30, 40].
- 2Count the replacement elements
The replacement sequence contains 3 elements: [200, 201, 202].
- 3Compare the sizes
The replacement is longer by 1 element.
The list grows from 5 elements to 6 elements.
Debugging Shared References
Unintended mutations usually begin with an incorrect assumption: treating assignment as if it copied the list. To debug the problem, trace how each variable was created. If one variable was assigned directly from another list variable, they share one list object. Next, locate the operation that modifies the list, including slice assignment, and determine which other names can see that same object.
Common mistake Assuming alias = original creates a copy.
What it looks likeoriginal = [1, 2, 3], followed by alias = originalWhy it failsAssignment creates a reference to the existing list, so both variables refer to the same object.
Do this insteadUse original[:] or list(original) when an independent list is required.
Common mistake Forgetting that a replacement sequence can change list length.
What it looks likeReplacing a two-element slice with a three-element sequence
Why it failsSlice assignment replaces the selected elements with the complete replacement sequence, so a longer replacement grows the list.
Do this insteadCount the selected elements and replacement elements before predicting the result.
Common mistake Changing a shared list when the original must be preserved.
What it looks likeModifying alias and then expecting original to remain unchanged
Why it failsThe two variables refer to the same list object.
Do this insteadCreate a shallow copy before modifying the second list.
Be explicit about intent. If later logic needs the original list, make a copy before modifying another version. If changing the original list in place is intentional, document that intent so a future reader does not mistake the shared mutation for a bug.
Practice the Trace
A list has six elements. A slice selects two elements. Predict the list-length change in each case: the replacement has two elements, the replacement has one element, and the replacement has four elements. Then decide whether you would assign a second variable directly or create a copy if the original list must be preserved.
Hints
- Compare the selected slice size with the replacement sequence size.
- Equal sizes preserve length.
- A shorter replacement shrinks the list, and a longer replacement grows it.
- Use [:] or
list()when you need an independent list.
- 1Trace how each variable was created: direct assignment means a shared reference.
- 2Identify the list operation that changes the object.
- 3Count the elements selected by the slice.
- 4Count the elements in the replacement sequence.
- 5Decide whether the list shrinks, stays the same length, or grows.
- 6Use [:] or
list()first when the original list must remain unchanged.
Key Takeaways
- 1Assigning one list variable to another creates a shared reference, not a copy.
- 2Use [:] or
list()to create a shallow copy with the same elements and an independent list object. - 3Slice assignment replaces multiple elements in an existing list.
- 4A shorter replacement shrinks the list, an equal-sized replacement preserves its length, and a longer replacement grows it.
- 5When debugging an unexpected mutation, trace shared references and count both the selected and replacement elements.
At a glance
- Assignment gives another variable a reference to the same list; it does not copy the list.
- A shallow copy made with [:] or
list()lets two variables refer to separate list objects with the same elements. - Slice assignment updates a selected range in place and can replace it with a sequence of a different size.
- Always compare slice size with replacement size to predict whether the list will shrink, stay the same length, or grow.
- When preserving the original matters, copy first and make in-place changes intentional.