Function Parameters and Mutable Objects
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 program uses two variables, a and b, for what appears to be the same list. If changing the list through b also changes what you see through a, the program may not contain two lists at all. It may contain one list with two variable names referring to it. This relationship is called aliasing.
The assignment b = a creates an alias, not an independent copy. After that assignment, a and b refer to the same object.
Checking Identity
Python provides the is operator for testing object identity. The expression a is b is True when both variables refer to the same object and False when they refer to different objects. This is different from ==. The == operator tests whether two objects have equal values. Two variables can therefore contain equal-looking lists while still referring to different list objects.
True
TrueBoth tests are True in this example, but they answer different questions. The equality test says that the values match. The identity test says that a and b refer to the same list object. The identity result is the important clue when investigating aliasing.
Mutation Through an Alias
What do you think happens?
After b = a and b.append(4), what will a contain?
Reveal answer
Answer: [1, 2, 3, 4]
The assignment b = a gives both names access to one list. Because the list is mutable, modifying it through b changes the one shared object, which is also visible through a.
a = [1, 2, 3] b = a b.append(4) print(a) print(b)
Parameters and Shared Lists
A function parameter can refer to the same mutable list that the caller supplies. If the function modifies that list through its parameter, the caller can observe the modification through its original variable. The parameter is another name referring to the object passed into the function; it does not automatically make an independent list copy.
["old", "new"]When debugging a function that unexpectedly changes a caller's list, inspect whether the function parameter and the caller's variable refer to the same object. The is operator helps verify that relationship.
Aliases and Independent Copies
If a program needs two lists whose later modifications are independent, create a copy explicitly. The source identifies a[:] and list(a) as ways to create an independent copy of a list. In contrast, b = a preserves the shared relationship.
| Operation | Relationship | Effect of modifying b |
|---|---|---|
| b = a | b and a refer to the same list | The modification is visible through a |
| b = a[:] | b refers to an independent list copy | The modification does not affect a |
| b = list(a) | b refers to an independent list copy | The modification does not affect a |
[1, 2, 3, 4]
[1, 2, 3, 4]
[1, 2, 3, 5]Tracing an Unexpected Change
Aliasing bugs often appear as an unexpected list change: one part of a program modifies a list, and another variable appears to change without being assigned. Trace the variables that refer to the list, then test likely pairs with is. If the test is True, a modification through either name affects the same mutable object.
Assuming b = a creates a second list.
The assignment makes b refer to the same list object as a.
Fix:
Use b = a[:] or b = list(a) when an independent list is required.Using == when the debugging question is whether two variables share one object.
Equality compares values, not object identity.
Fix:
Use a is b to test whether the variables refer to the same object.Forgetting that a function parameter can refer to the caller's mutable list.
The parameter can refer to the same list supplied by the caller.
Fix:
Check the identity relationship and create a list copy when the function should work independently.
When a list must not be changed through another variable or function parameter, make the independence explicit with a[:] or list(a). When a change is unexpected, test whether the two variables are aliases before searching for a more complicated cause.
Practice the Trace
A program contains a list named scores. Another variable receives scores with the assignment backup = scores. Before any modification, decide what scores is backup will return. Then decide what scores will contain after backup is modified. Finally, describe one change that would make backup independent from scores.
Hints
- Ask whether the assignment creates an alias or a copy.
- Use the difference between is and == to identify the relevant test.
- An independent list can be created with a slice or the list constructor.
Tracing the Shared Object
Let scores = [10, 20], backup = scores, and then modify backup by adding 30. What identity relationship exists, and what values are visible through both variables?
Identify the assignment: The assignment backup = scores creates an alias rather than an independent copy.
Test identity: scores is backup is True because both variables refer to the same list object.
Apply the mutation: Adding 30 through backup modifies the shared list.
Inspect both names: Both scores and backup show [10, 20, 30] because each name refers to the modified object.
The variables are aliases. To prevent the shared change, create backup with scores[:] or list(scores).
Key Takeaways
- Aliasing means that multiple variables refer to the same object.
- The assignment b = a creates an alias, not a copy.
- Use is to test identity and == to test equality of values.
- A mutation to a shared list is visible through every variable that refers to that list, including a function parameter.
- Use a[:] or list(a) to create an independent list copy when later modifications must remain separate.
Key Takeaways
- Aliasing occurs when two or more variables refer to one mutable object.
- The is operator reveals whether two variables refer to the same object.
- Mutating a shared list through one variable changes what other aliases observe.
- Function parameters can refer to the caller's list and mutate that shared object.
- Use a[:] or list(a) to create an independent list instead of an alias.