Copying & References
Overview
Understand how references are passed in Python, and contrast shallow copies against deep copies for mutable nested objects.
Learning Objectives
- Understand variables references binding assignments.
- Contrast shallow copy with deep copy allocations.
- Copy nested dictionary/list data securely.
Concept Explanation
Assignment binds names to references. Shallow copies duplicate containers but reuse nested element references. Deep copies recursively duplicate all elements.
Code Examples
Example 1 — Basics
This example introduces the fundamental syntax and concepts.
import copy
a = [1, 2]
b = copy.copy(a)
c = copy.deepcopy(a)
Example 2 — Everyday Usage
This example demonstrates a realistic scenario handling business parameters.
import copy
original = [[1, 2]]
shallow = copy.copy(original)
shallow[0].append(99)
# Mutates original nested list too!
print(original)
Example 3 — Advanced Example
This example shows clean, production-grade code structure following senior development standards.
import copy
def clean_records(raw_dict):
# Deep copy keeps original data intact
cleaned = copy.deepcopy(raw_dict)
if 'token' in cleaned:
cleaned['token'] = 'MASKED'
return cleaned
payload = {'user': 'alex', 'token': 'abc', 'meta': {'active': True}}
print(clean_records(payload))
print(payload)
Visual Flow
The following execution flow represents the step-by-step evaluation inside the interpreter:
Shallow Copy → Copy container → Point to identical child nodes
Deep Copy → Recursively clone container → Allocate separate child nodes
Common Mistakes
Review these common pitfalls when working with this topic:
- Using shallow copies (like list.copy() or dict.copy()) on nested structures.
- Mutating nested lists expecting copied templates to remain unchanged.
- Using deepcopy unnecessarily on simple non-nested arrays.
- Modifying arguments directly, causing side-effects in caller scopes.
Best Practices
Enforce these Pythonic best practices in your codebase:
copied_dict = original_dict.copy() # Shallow copy for nested structures
import copy
copied_dict = copy.deepcopy(original_dict) # Safe deep copy
Performance Notes
Keep these optimization guidelines in mind for performance-sensitive hotpaths:
- deepcopy() is slow because it traverses nested objects and tracks duplicate references recursively.
Quick Revision
Use these key summaries for last-minute revision:
- Assignment binds labels to references.
- Shallow copies duplicate top containers.
- Nested references are shared in shallow copies.
- Deep copies duplicate nested items recursively.
- deepcopy() is slower than copy().
- Avoid modifying arguments directly.