Deep Copy vs. Shallow Copy: Fundamental Methods for Python Object Replication

In Python, when we need to copy an object, we often encounter three different operations: “assignment”, “shallow copy”, and “deep copy”. Their behavioral differences directly affect the independence of the copied object, especially when dealing with nested mutable objects (such as lists, dictionaries, etc.). Understanding their distinctions is crucial.

1. Assignment: Just “Labeling”, Not Copying the Object Itself

In Python, when you assign one variable to another, the new variable points to the reference of the original object, not creating a new object. At this point, both variables share the same object. Modifying the content of the object pointed to by one variable will affect the other variable as well.

Example:

a = [1, 2, 3]  # List 'a' is a mutable object
b = a          # 'b' and 'a' point to the same list object
b.append(4)    # Modify the content of 'b' (add element 4)

print(a)  # Output: [1, 2, 3, 4], 'a' is also modified!

Reason: Since lists are mutable, b.append(4) directly modifies the original list. a and b are just different “labels” for the same object.

2. Shallow Copy: Copy the Outer Layer, Inner Layers “Share” the Original Object

A shallow copy creates a new object but only copies the outermost elements of the object. Nested objects inside (e.g., lists within lists, dictionaries within dictionaries) still reference the original object. Therefore, modifying the nested objects will affect the original object.

Implementation: Use copy.copy(), list slicing [:], or the copy() method of dictionaries.

Example:

import copy

a = [[1, 2], [3, 4]]  # Outer list with nested inner lists
b = copy.copy(a)      # Shallow copy: new outer list, but inner lists still reference the original object

# Modify the first element of the inner list
b[0].append(5)  

print(a)  # Output: [[1, 2, 5], [3, 4]], the inner list of the original list is modified!

Reason: The shallow copy only copies the outer list [ [1,2], [3,4] ], but the inner sublists [1,2] and [3,4] remain the original objects. Modifying b[0] directly affects the sublist in the original list a.

3. Deep Copy: Recursively Copy All Levels, Completely Independent

A deep copy recursively copies all levels of objects, including nested sub-objects. It creates a completely independent new copy of the original object. Modifying either the outer or inner objects will not affect the original object.

Implementation: Use the copy.deepcopy() function.

Example:

import copy

a = [[1, 2], [3, 4]]  # Nested list
b = copy.deepcopy(a)  # Deep copy: copies all levels of objects

# Modify the first element of the inner list
b[0].append(5)  

print(a)  # Output: [[1, 2], [3, 4]], the original list is unaffected!

Reason: The deep copy not only copies the outer list [ [1,2], [3,4] ] but also recursively copies the inner sublists [1,2] and [3,4]. Thus, b and a are completely independent objects.

How to Choose the Copy Method?

Copy Type Applicable Scenarios Key Point
Assignment (=) Simple immutable objects (e.g., int, str) Share references; modifications affect originals
Shallow Copy (copy.copy()) Single-level nested mutable objects (e.g., list of tuples) Only outer layer copied; inner nested objects share originals
Deep Copy (copy.deepcopy()) Multi-level nested mutable objects (e.g., list of lists) Completely independent; all levels copied

Common Misconceptions

  1. Misunderstanding of Immutable Objects: For immutable objects like int and str, assignment, shallow copy, and deep copy have similar effects because modifying an immutable object creates a new object, not affecting the original.
  2. Confusing Shallow and Deep Copies: Shallow copy only handles “single-level nesting”; deep copy handles “all levels of nesting”.
  3. Ignoring Nested Structures: If an object contains nested mutable objects (e.g., [ [1], [2] ]), deep copy is required to ensure complete independence.

Summary

  • Assignment: Shares references; modifications affect the original (only for simple scenarios).
  • Shallow Copy: Copies the outer layer; inner layers share the original (for single-level nesting).
  • Deep Copy: Recursively copies all levels; completely independent (for multi-level nesting).

Understanding these differences helps avoid accidental modifications to the original object when handling complex data structures, enabling more reliable code.

Xiaoye