CHAPTER 08 · BEGINNER4 min read

Mutability and copying

Trace shared references, distinguish rebinding from mutation, and copy nested data intentionally.

Python 3.12+Free to readModule 2 of 13
YOUR NEXT SMALL WINS

By the end, you’ll be able to…

  • Predict when two names observe the same list mutation.
  • Distinguish identity from equal contents.
  • Choose shallow or deep copying based on the structure you need to isolate.

01Two names can refer to one object

Assignment does not automatically duplicate data. When backup = tasks runs, both names refer to the same list. Appending through either name changes that one shared object, so both names reveal the change. Imagine two labels attached to the same basket rather than two baskets containing matching items. This model explains why a supposed backup can change unexpectedly.

Rebinding a name is different from mutating the object it refers to. After backup = ['Rest'], backup refers to a newly created list, while tasks still refers to the original. The equals sign binds a name; an operation such as append changes a list. Trace the objects and arrows separately if the values are difficult to follow. The distinction also applies when collections are passed into functions later.

shared_names.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

02Equality and identity answer different questions

The == operator asks whether values compare equal. The is operator asks whether two references identify the very same object. Two separately constructed lists can have equal contents without being one list. Sharing is therefore not something you can infer merely from how print displays an object. Use identity checks to investigate aliases when learning, not as a substitute for value comparison.

For ordinary numbers and strings, compare values with ==. Python may reuse some immutable objects internally, and programs should not depend on those implementation choices. A common appropriate identity check is value is None, because None is a unique singleton used to represent absence. This lesson uses lists so the relationship between independent construction and shared identity is easy to see.

identity_and_equality.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

03A shallow copy duplicates the outer container

list.copy(), a full list slice, and list(existing_list) each create a new outer list containing references to the existing items. This is called a shallow copy. With a flat list of immutable values, it often provides exactly the independence you need: replacing or appending an outer item does not change the original list's arrangement.

Nested mutable items require more thought. Copying a list of rows gives you a new outer list, but each row is still shared. Replacing copy[0] changes one outer slot; changing copy[0][0] mutates a shared row. Ask which level of the structure your next operation will modify. A shallow copy is neither a broken copy nor a promise of complete independence; it has a specific boundary.

shallow_copy.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.

04Copy the level your task needs

The standard library's copy module provides deepcopy for recursively copying supported nested structures. The import line below makes that tool available; the modules lesson will explain imports in more depth. For these simple nested lists, deepcopy creates independent inner lists, so editing a copied row leaves the original data intact.

Do not reach for deep copying every time two names might share something. Sometimes shared state is intentional, and sometimes constructing a small new result is clearer than duplicating a large object graph. Deep copying can also copy more data than necessary and has special rules for some object types. State the requirement first: 'editing these copied rows must not edit the source rows.' Then choose an operation that fulfills that requirement and verify it with one small mutation.

independent_rows.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
LET IT CLICK

The ideas worth keeping.

  • Assignment can create another name for the same object.
  • Mutation changes an object; rebinding changes which object a name refers to.
  • Shallow copies isolate the outer container; nested mutable data may require a deeper copy.
TURN UNDERSTANDING INTO SOMETHING YOU CAN DO

Make it yours.

Type and test your code right here in the interactive workspace. Run your solution, check the output, and compare with the worked guide when ready.

01

Make a flat draft independent

Start with topics = ['strings', 'lists']. Create a shallow copy called draft, append functions to draft, and print both lists. topics must retain only its original two items.

your_turn_1.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.pyPython
topics = ["strings", "lists"]draft = topics.copy()draft.append("functions")print(topics)print(draft)

The two lists have independent outer structures. Sharing the immutable string items is harmless because appending changes only the draft's outer list.

02

Protect a nested grade table

Given grades = [['Ada', 7], ['Mira', 8]], make an independent copy named revised. Change Ada's score to 9 in revised and print both structures. The original score must remain 7.

your_turn_2.py🐍Python
Ctrl + ↵
Output
Click Run or press Ctrl+Enter
Output will appear here after you run the code.
Explore a worked solution
one_possible_solution.pyPython
from copy import deepcopygrades = [["Ada", 7], ["Mira", 8]]revised = deepcopy(grades)revised[0][1] = 9print(grades)print(revised)

A shallow outer copy would still share Ada's mutable row. deepcopy duplicates the nested list structure, which makes this particular inner mutation independent.

A SMALL QUESTION. A USEFUL NEXT STEP.

What stayed with you?

Check the ideas while they’re fresh. Your answers stay in this page and feedback appears as you go.

A LITTLE ACTIVE RECALL0 / 3 answered
01After a = [1]; b = a; b.append(2), what is a?
02What is guaranteed after b = a.copy() for a nested list?
03Two lists print identically. Which expression checks whether they are the same object?
⚡CODING CHALLENGE
🔒Required to Mark Lesson Complete

Make a flat draft independent

Start with topics = ['strings', 'lists']. Create a shallow copy called draft, append functions to draft, and print both lists. topics must retain only its original two items.

EXPECTED OUTPUT
strings,lists
topics.copy()
challenge.pyPython 3
Ctrl + ↵
Execution Console
Click "Run & Verify" (or press Ctrl + Enter) to test your code against the challenge.

Keep exploring.

The official references behind this chapter, when you want a second angle or the full details.

MODULE 02 · PRACTICAL SELF-CHECK

Pause. Put the pieces together.

You’ve reached the end of Text and collections. Before moving on, use this task to check what you can do independently.

Clean a label, organize records, and demonstrate when a copy protects the original collection.

Try it in your own environment and write down the result. This is a self-check; reading completion does not evaluate your code.

Review this module

One chapter closer.

Reading is a start. Trying it yourself makes the connection.

Solve the hands-on coding challenge in the knowledge section to verify your code and unlock chapter completion.