The id() Function and Object Identity
Variables are references to objects in memory, not the objects themselves.
A List with Two Names
Suppose two variable names are connected to one list. The important question is not only what values the list contains. You must also ask whether both names refer to the same list object. Variables are references to objects in memory, not the objects themselves. This distinction explains why a change made through one variable can appear when the list is viewed through another variable.
The diagram represents two references leading to one list object. The variable names are not two separate lists merely because there are two names. If both names point to the same object, changing that object through either name affects what the other name observes.
Reading Object Identity
Object identity is the question of whether two variable references lead to the same object. The id() function is the tool named in this topic for examining that identity. When you reason about two variables, use id() together with the reference model: equal-looking contents do not by themselves tell you whether the variables refer to one shared object or to separate objects.
The practical value of object identity is diagnostic. If an unexpected change appears through more than one variable, ask whether those variables reference the same object. The id() function provides a way to inspect that identity relationship.
Tracing a Shared Change
Two Variables, One List
A list is associated with two variable names. Predict what happens when the list is changed through one of those names.
Start with the references: Treat each variable name as a reference to an object. If both names point to the same list object, there is only one list being referred to.
Change the list through one name: The change is made to the shared list object, not to a private list belonging only to the variable used to make the change.
Inspect the other name: Because the other variable still refers to that same object, the change is visible through that variable as well.
A change made through one variable affects every variable that points to the same list object.
Making an Independent Copy
When you need a second list that can be changed independently, use full slice notation. The source pack gives the form mylist = shoplist[:]. This creates an independent copy rather than another reference to the same list object. The copied list begins with the contents of the original, but later changes to one list do not represent changes made to the other shared object.
Choosing Between Sharing and Copying
You want a second variable to begin with the contents of an existing list, but you do not want later list changes to be shared.
Identify the risk: A second variable that points to the same list object will share changes with the first variable.
Use full slice notation: Write mylist = shoplist[:]. The full slice notation is the source pack's stated way to create an independent copy.
Reason about later changes: The two variable names now refer to separate list objects. Their starting contents come from the original list, but the objects are independent.
Use full slice notation when you need an independent list copy instead of another reference to the original list.
Mistakes with Shared References
Assuming that two variable names automatically mean two list objects.
Multiple variables can point to the same object.
Fix:
Trace where each variable points. Use object identity reasoning and the id() function when you need to inspect that relationship.Expecting a change through one variable to remain visible only through that variable.
A change through one variable affects all variables pointing to the same object.
Fix:
Before changing a list, decide whether shared behavior is intended. If not, create an independent copy with full slice notation.Ignoring object identity because two lists have the same contents.
Contents and identity answer different questions.
Fix:
Use id() as an identity check and reason separately about the values contained in each list.
Check Your Prediction
Imagine that two variables point to the same list object. A change is made through the first variable. Before checking the second variable, predict whether it shows the original list contents or the changed contents. Then explain how full slice notation would change the result.
Hints
- Start by drawing one list object and two arrows or references leading to it.
- Ask whether the change is made to a variable name or to the shared list object.
- For independence, use the source form mylist = shoplist[:].
What do you think happens?
If two variables point to the same list object, what happens when the list is changed through one variable?
Reveal answer
Answer: Every variable pointing to that object reflects it
The variables are references to the same object. The change affects that object, so it is visible through every reference to it.
The Reference Model
- Variables are references to objects in memory, not the objects themselves.
- Multiple variables can point to one list object, so a change through one variable affects the others.
- The id() function helps you reason about and inspect object identity.
- Equal contents do not by themselves establish that two variables refer to the same object.
- Use full slice notation, such as mylist = shoplist[:], to create an independent list copy.
Key Takeaways
- A variable refers to an object; it is not the object itself.
- Several variables may refer to one list, and changes to that shared list are visible through every reference.
- Object identity is separate from list contents, and id() can be used when investigating that identity.
- Full slice notation creates an independent list copy so later changes are not shared through the same list object.