Concepts / Shallow vs. Deep Copying

Shallow vs. Deep Copying

Identity (is) checks whether two variables refer to the same object in memory; equivalence (==) checks whether two objects have the same value.

  • Programming

The Backup That Was Not Independent

Imagine creating a backup of a list and then changing the original. Whether the backup changes too depends on one question: did you create a separate object, or did both variables become names for the same object? This is the foundation for understanding copying in Python. The same visible data can belong to one shared object or to multiple separate objects.

Two Ways Objects Can Match

Identity and equivalence describe different relationships. Identity asks whether two variables refer to the exact same object in memory. Python checks this relationship with the is operator. Equivalence asks whether two objects contain the same value or data. Python checks this relationship with the == operator.

refers torefers torefers toavariablelist object[1, 2, 3]bvariablelist object[1, 2, 3]cvariable
Do these variables point to the same object, or to separate objects containing similar data?

Same data, different identity

Consider two separately created lists that each contain the values 1, 2, and 3.

Compare their values: The lists contain the same elements, so they are equivalent. The == comparison is True.

Compare their identity: They are two separate list objects, so they are not identical. The is comparison is False.

Interpret the result: Matching contents do not prove that two variables refer to the same object.

The lists are equivalent without being identical.

Identity and Equivalence

Identity means that two variables refer to the same object. Equivalence means that the objects referred to by two variables have the same value or data.

always impliescan still haveidentityequivalenceseparate objects
Which relationship is guaranteed when two variables share one object, and which relationship can exist between separate objects?

If two variables refer to one object, that object has one identity and one value, so identity implies equivalence. However, two separate objects can contain the same data, so equivalence does not imply identity.

Aliasing Versus a New List

Assigning one variable to another does not create a new list. It creates an alias: both variable names refer to the same existing object. By contrast, creating a new list literal creates a separate list object, even when the elements match those of another list.

SituationObject relationshipIdentity resultMutation consequence
One variable assigned to anotherBoth variables refer to the same objectis returns TrueA change through one variable is visible through the other
A separate list is created with the same elementsVariables refer to different list objectsis returns FalseThe lists are not automatically the same object

The source of the reference determines whether two variables are aliases or refer to separate objects.

refers torefers torefers torefers toashared listone objectblist objectone objectalist objectanother objectb
What changes when two variables share one list object instead of referring to separate lists?

Nested Copying Caution

When analyzing a shallow or deep copy, the key question remains whether the objects that matter are shared or independent. The supplied material establishes the general rule for aliases and separate objects, but it does not specify a particular copying function or give a complete rule for nested structures. Therefore, do not assume that the word copy alone proves independence. Check the identity relationship of the objects involved.

may refer tomay also refer toor may refer tooriginalobjectidentity to testcopyobjectidentity to test
After a copying operation, which object should you test to determine whether the relevant reference is shared?

Strings and Lists

Strings and lists illustrate why identity behavior must be understood together with mutability. Strings are immutable, meaning they cannot be changed after creation. Python can therefore reuse string objects when possible; this behavior is called string interning. Lists are mutable, meaning their contents can be changed. Python creates separate list objects when two lists are created with the same elements, rather than treating matching list contents as proof of shared identity.

safe reuse when possibleseparate creationstringimmutablestringmay be reusedlistmutablelistseparate objects
How do strings and lists differ when Python manages objects that have matching data?
TypeMutabilityIdentity behavior described in the sourceWhy it matters
StringImmutablePython can reuse string objects when possibleReusing an object is safe because its contents cannot be changed
ListMutableTwo lists with the same elements are separate objects when separately createdChanging a shared list can affect every variable referring to it

Mistakes That Cause Mutation Bugs

  • Assuming equal-looking lists are the same object.

    Lists can be separate objects while still being equivalent.

    Fix: Use == to compare data and is to test whether the object itself is shared.

  • Treating assignment as a copy.

    The assignment creates an alias, so both variables refer to the same list.

    Fix: Decide explicitly whether shared data or an independent object is intended.

  • Expecting a backup to protect data without checking identity.

    Both variables may refer to the same mutable list.

    Fix: Check the identity relationship before relying on the backup.

  • Assuming string behavior applies unchanged to lists.

    Strings are immutable, while lists are mutable, so Python handles them differently.

    Fix: Consider the object's mutability when reasoning about identity and sharing.

Practice the Identity Test

MEDIUM

A variable named scores refers to a list. A second variable named backup is then assigned from scores. Predict the result of comparing scores and backup with is. Next, imagine that another list is created separately with the same elements as scores. Predict whether the separate list is equivalent to scores and whether it is identical to scores.

Hints
  • Ask whether the second variable was made by aliasing an existing object or by creating a new list.
  • Use == for matching data and is for shared identity.
  • Remember that modifying a shared mutable list is visible through both aliases.

Reading the two comparisons

Compare an alias of a list with a separately created list containing the same data.

Alias comparison: The alias and the original refer to one list object, so they are identical and therefore equivalent.

Separate-list comparison: The separately created list has the same elements, so it is equivalent to the original, but it is not the same object.

Choose the operator: Use is when the question concerns one shared object. Use == when the question concerns matching data.

Identity and equivalence must be checked with different operators because they answer different questions.

Working Rule

  1. Use is to ask whether two variables refer to the same object.
  2. Use == to ask whether two objects contain the same value or data.
  3. Identity always implies equivalence, but equivalent objects can still be separate.
  4. Assignment can create an alias rather than an independent copy.
  5. Mutability matters: changes to a shared list are visible through every alias, while strings cannot be changed after creation.

Key Takeaways

  • Identity describes whether variables refer to the same object; equivalence describes whether objects contain the same data.
  • The is operator tests identity, while the == operator tests value equivalence.
  • An alias gives multiple variables access to one object, so mutation through one alias is visible through the others.
  • Separately created lists can be equivalent without being identical.
  • Immutable strings and mutable lists behave differently because their contents have different mutability rules.