Concepts / Shallow vs. Deep Copying

Shallow vs. Deep Copying

When analyzing a shallow or deep copy, the key question remains whether the objects that matter are shared or independent.

  • Programming
Interactive lab

Try it: Shallow vs Deep Copies of Nested Lists

Why b = a copies nothing, why a[:], list(a) and a.copy() copy only the outer list (the inner lists stay shared, so a[0] is b[0]), and how copy.deepcopy copies every level — checked with is and ==.

How it works

  1. b = a binds a second name to the same list object: a is b.
  2. a[:], list(a) and a.copy() make one new outer list whose slots copy the references: a is not b, but a[0] is b[0].
  3. copy.deepcopy copies every list recursively (a memo keeps a list that appears twice as one copy); ints are immutable and simply shared.
  4. Mutating a list reachable from both names (append, item assignment) is seen through both; rebinding a name changes only that name.
  5. is compares identity; == compares values item by item.

Default run (9 steps): The program builds a nested list, copies it one way, then changes one of the two names. … Done. a = [[1, 2, 9], [3, 4]] | b = [[1, 2, 9], 7] | a is b False | a == b False | a[0] is b[0] True

Simplified: Small nested lists of ints; the list numbers L1, L2… stand in for identities (not real id() values). Equal small ints are one cached object in CPython, so a[0] is b[0] can be True for ints.

Educational simulation

Loading the simulation…

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.

avariablelist object[1, 2, 3]bvariablelist object[1, 2, 3]cvariablerefers torefers torefers to
Do these variables point to the same object, or to separate objects containing similar data?
Worked example

Same data, different identity

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

  1. 1
    Compare their values

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

  2. 2
    Compare their identity

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

  3. 3
    Interpret the result

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

Result

The lists are equivalent without being identical.

Identity and Equivalence

Definition

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.

identityequivalenceseparate objectsalways impliescan still have
Which relationship is guaranteed when two variables share one object, and which relationship can exist between separate objects?
Key point

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.

ashared listone objectblist objectone objectalist objectanother objectbrefers torefers torefers torefers to
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.

originalobjectidentity to testcopyobjectidentity to testmay refer tomay also refer toor may refer to
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.

stringimmutablestringmay be reusedlistmutablelistseparate objectssafe reuse when possibleseparate creation
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

Mutability affects whether sharing an object can produce visible changes through multiple variables.

Mistakes That Cause Mutation Bugs

  • Common mistake

    Assuming equal-looking lists are the same object.

    What it looks like

    Two separately created lists contain the same elements.

    Why it fails

    Lists can be separate objects while still being equivalent.

    Do this instead
    Use == to compare data and is to test whether the object itself is shared.
  • Common mistake

    Treating assignment as a copy.

    What it looks like

    One variable is assigned to another variable that already refers to a list.

    Why it fails

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

    Do this instead

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

  • Common mistake

    Expecting a backup to protect data without checking identity.

    What it looks like

    A list is modified through one variable, and the change appears through another variable.

    Why it fails

    Both variables may refer to the same mutable list.

    Do this instead

    Check the identity relationship before relying on the backup.

  • Common mistake

    Assuming string behavior applies unchanged to lists.

    What it looks like

    A learner expects two matching lists to be reused like matching strings.

    Why it fails

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

    Do this instead

    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.
Worked example

Reading the two comparisons

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

  1. 1
    Alias comparison

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

  2. 2
    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.

  3. 3
    Choose the operator

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

Result

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

Working Rule

  1. 1
    Use is to ask whether two variables refer to the same object.
  2. 2
    Use == to ask whether two objects contain the same value or data.
  3. 3
    Identity always implies equivalence, but equivalent objects can still be separate.
  4. 4
    Assignment can create an alias rather than an independent copy.
  5. 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.

Related concepts

More concepts starting with S