Understanding List Mutability and References
If an unexpected list change appears in two variables, check whether the variables are aliases before looking for a sorting or indexing mistake.
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 Change, Two Views
A list can be accessed through more than one variable. When two variables point to the same list object, the variables are aliases. A mutation made through one variable affects what is seen through the other variable because both names refer to the same list.
Tracing an Alias
Here, alias refers to the same list object as t. The append operation is made through alias, but the list viewed through t also changes. The important distinction is between changing the existing list and assigning a different list to a variable. Aliasing matters when the existing list is mutated.
If an unexpected list change appears in two variables, check whether the variables are aliases before looking for a sorting or indexing mistake.
Slicing for Independence
When you need a separate list that can be modified without changing the original list, create a defensive copy with orig = t[:]. This slicing operation gives orig an independent list. Later mutations made to the copied list can therefore be handled separately from the original data.
The key step is t[:]. It creates a separate list rather than another variable referring to the same list object. This makes slicing useful when the original data must be preserved while a working copy is changed.
Sorting Without Losing Data
Use sorted() when you want a new sorted list without modifying the original. Use the sort() method when you want to sort a list in place. If the original must remain available, another option is to create a defensive copy with slicing and then use sort() on that copy.
| Tool | Effect on original list | Useful choice when |
|---|---|---|
| sorted() | Does not modify the original | You need a new sorted list and want the original unchanged |
| sort() | Sorts the list in place | You intend to change the list itself |
| t[:] followed by sort() | Sorts the independent copy | You want sort() behavior without changing the original |
Choosing between sorted(), sort(), and sorting a defensive copy
Reference Checks
To investigate a suspected alias, compare whether two variables refer to the same list object rather than relying only on whether their contents look equal. Two separate lists can contain the same values, while aliases share the same list object. This distinction explains why mutating one variable can affect the other.
When debugging an unexpected change, trace every variable that may refer to the list. If independent data is required, make the relationship explicit with orig = t[:] before modifying the working list.
Common Reference Mistakes
Common mistake Treating an alias as an independent copy
What it looks likealias = tWhy it failsBoth variables point to the same list object, so a mutation through one variable affects the other.
Do this insteadUse orig = t[:] when you need an independent list.
Common mistake Using sort() when the original list must stay unchanged
What it looks likescores.sort()Why it failssort()changes the list in place.Do this insteadUse ordered = sorted(scores), or copy first and sort the copy.
Common mistake Assuming equal contents prove two lists are the same object
What it looks likeTwo variables each show [1, 2].
Why it failsSeparate lists can contain equal values without being aliases.
Do this insteadInvestigate whether the variables share the same list object.
Common mistake Naming a variable sorted
What it looks likesorted = [1, 2, 3]Why it failsThe variable shadows the built-in sorted function.
Do this insteadChoose another variable name, such as ordered.
Apply the Choice
You have a list named t. You need an ordered version for further work, but you must preserve the original order in t. Which approach should you choose: sorted(t), t.sort(), or orig = t[:] followed by orig.sort()? Explain why.
Hints
- Ask whether t itself is allowed to change.
- Remember that
sorted()creates a new sorted list. - Remember that t[:] creates an independent list.
Preserving the Original List
Choose a safe way to obtain a sorted version of t without changing t.
- 1Check the requirement
The original list must remain unchanged, so directly using
sort()on t is not the appropriate choice. - 2Choose a new-list operation
sorted(t)is suitable because it produces a new sorted list without modifying the original. - 3Choose the copy-and-sort alternative
You can also create orig = t[:] and then use
sort()on orig, because orig is an independent list.
Use sorted(t) when you want a new sorted list directly, or use t[:] before sort() when you want to sort a defensive copy.
Working Rule
- 1Aliasing means two variables point to the same list object, so mutation through one variable affects the other.
- 2Use orig = t[:] to create an independent list that can be modified safely.
- 3Use
sorted()for a new sorted list that leaves the original unchanged. - 4Use
sort()when changing the existing list in place is intended. - 5Avoid sorted as a variable name because it shadows the built-in function.
Key Takeaways
- Aliasing makes two variables views of the same list object.
- Mutating an aliased list affects every variable that refers to that object.
- Slicing with t[:] creates a defensive copy for independent changes.
sorted()returns a new sorted list, whilesort()changes a list in place.- Never use sorted as a variable name because it shadows the built-in function.