Understanding Mutability in Python
Aliasing occurs when two or more variables refer to the same object in memory. The assignment b = a creates an alias, not a copy.
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
Suppose a variable a refers to a list. If you then write b = a, it is tempting to think that Python creates a second list for b. Instead, both variable names refer to the same list object. This shared reference is called aliasing. Once you understand that there is one shared object rather than two independent lists, unexpected changes become easier to explain.
Checking Object Identity
The is operator tests object identity: whether two variables refer to the same object. After b = a, the expression a is b is True because both names refer to the same list. This differs from ==. The == operator tests whether two objects have equal values. Therefore, two variables can contain objects with equal values without referring to the same object.
a = [10, 20] b = a same_object = a is b same_values = a == b
How Mutation Spreads
A list is mutable, which means its contents can be modified after the list is created. When a and b are aliases for the same list, modifying the list through b changes the one shared object. Reading the list through a then shows that modification too. The variable used for the modification does not determine which list changes; the shared object is what changes.
What do you think happens?
After these statements, what will a contain? a = [10, 20] b = a b.append(30)
Reveal answer
Answer: [10, 20, 30]
The assignment b = a makes b an alias for the same list as a. The modification through b changes that shared list, so the new element is visible through a.
a = [10, 20]
b = a
b.append(30)
print(a)
print(b)
Output:
[10, 20, 30]
[10, 20, 30]Copying Instead of Aliasing
Use an explicit copying operation when two lists must be independent. The source identifies a[:] and list(a) as ways to create an independent copy. After copying, the two lists are separate objects. A modification to one list does not affect the other.
Alias or Independent Copy
Compare b = a with b = a.copy() when a begins as [10, 20].
Create an alias: With b = a, both names refer to the same list object. A modification through b is visible through a.
Create a copy: With b = a.copy(), b refers to an independent copy of the list. A modification to b does not affect a.
Choose deliberately: Use the alias when shared changes are intended. Use an explicit copy when the lists must remain independent.
b = a shares one list with a. b = a.copy() creates a separate list with the same starting values.
Output:
[10, 20]
[10, 20, 30]Tracing an Unexpected Change
Aliasing often appears as a debugging mystery: a list changes, but the code that reads the list does not seem to modify it. The missing connection may be another variable that refers to the same object. Start by identifying the variables that might share the list, then use is to test their identity. If the test is True, a modification through either variable can explain the unexpected change.
items = ["pen", "book"] backup = items backup.append("lamp") print(items)
Output:
["pen", "book", "lamp"]Assuming b = a creates an independent list
The assignment creates an alias. Both names refer to one shared list, so the modification is visible through a.
Fix:
Use b = a[:] or b = list(a) when b must refer to an independent copy.Using == when the question is whether two variables share one object
Equality tests values, not object identity.
Fix:
Use a is b to test whether the two variables refer to the same object.Treating an unexpected change as if it happened without a cause
Another variable may be an alias for the same mutable list.
Fix:
Check likely aliases with is and decide whether an explicit list copy is needed.
Choosing the Reference Intentionally
| Statement | Relationship | Effect of modifying b |
|---|---|---|
| b = a | a and b refer to the same list | The change is visible through a |
| b = a[:] | b refers to an independent copy | The change does not affect a |
| b = list(a) | b refers to an independent copy | The change does not affect a |
Practice the Reference Trace
Consider this sequence: values = [1, 2] other = values other.append(3) Predict the result of values is other, then predict the contents of values. Finally, explain what assignment could create an independent list instead.
Hints
- Ask whether other = values creates an alias or a copy.
- Use is for the identity question.
- An independent list can be made with a slice or the list constructor.
- Aliasing means that multiple variable names refer to the same object.
- The assignment b = a creates an alias rather than a copy.
- Use is to test whether two variables refer to the same object; use == to test equality of values.
- Because lists are mutable, a modification through one alias is visible through every other alias.
- Use a[:], list(a), or another explicit copying operation when the lists must be independent.
Key Takeaways
- Aliasing occurs when two or more variables refer to one shared object.
- Writing b = a makes b an alias for a's object; it does not create an independent list.
- The is operator checks identity, while == checks equality of values.
- Mutating a shared list through one variable changes what every alias sees.
- Use a[:], list(a), or an equivalent explicit copy when independent list contents are required.