Copy Without Hiding Shared Data

Create a new outer collection deliberately while keeping shared nested mutable values visible and stating which object a function changes.

When two names refer to one collection, they are aliases. That is useful when two parts of a program should share changes. When a program needs a separate working collection, plain assignment is not enough. It needs a copy.

Copy a Flat Collection

The .copy() method creates a new outer collection containing the same items:

There are now two list objects:

original ─────> list A: [18, 21]
working  ─────> list B: [18, 21, 23]

The copied numbers can safely appear in both lists because numbers do not change in place. Appending to list B changes only its outer list.

Lists, dictionaries, and sets all provide .copy():

Each copy is a new outer collection. Appending to readings_copy, assigning a new key in by_sensor_copy, or adding to active_copy leaves the corresponding outer source collection unchanged.

Q1. Predict a flat list copy

What does this program display?

Choose one

Select one choice, then check.

HintCount the outer lists

.copy() creates list B before append changes it.

SolutionOnly the copied list grows

original still refers to list A, [18, 21]. working refers to list B, which becomes [18, 21, 23].

Not attempted
Review

Not marked done.

A Shallow Copy Can Still Share Nested Lists

The copy made by .copy() is a shallow copy. It creates a new outer collection, but it does not recursively copy mutable values stored inside that collection.

Consider a dictionary whose values are lists:

The outer dictionaries are separate, but both "north" entries refer to the same inner list:

original ─────> dictionary A ── "north" ──┐
                                           ├──> list N: [18, 21]
working  ─────> dictionary B ── "north" ──┘

Appending through either dictionary changes list N:

An outer change remains independent:

These two results are not contradictory. The dictionaries are separate; the inner north list is shared.

OperationDictionary ADictionary BShared list N
working = original.copy()unchangednew outer copy[18, 21]
working["north"].append(23)same outer keyssame outer keys[18, 21, 23]
working["west"] = [19]no "west" keygains "west"unchanged

Q2. Trace a shared nested list

What does original["north"] contain after this code runs?

Choose one

Select one choice, then check.

HintDraw the inner object separately

.copy() created another dictionary, not another list for each value.

SolutionThe nested append is shared

Both dictionaries contain a reference to the same north list. Appending 23 through working changes that list, so original["north"] is [18, 21, 23].

Not attempted
Review

Not marked done.

Return a Changed Flat Copy

A function can leave the caller's flat list unchanged by copying before it makes corrections:

The indexed assignment changes one position in the copied list. The function returns that changed copy:

This function works with a flat list of numbers. If its input contained nested lists, the ordinary .copy() would still share those inner lists. The function contract and the data shape must agree.

Q3. Return a corrected copy

Repair the function so it returns corrected readings without changing the caller's list.

Editable Python

Command/Ctrl + Enter. Python runs in your browser.

Ready to run.

HintCreate the second outer list first

Replace the plain assignment with readings.copy() before the loop changes any position.

SolutionCorrect only the copy
Not attempted
Review

Not marked done.

.copy() creates a new outer list, dictionary, or set. Flat outer changes are then independent, but nested mutable values remain shared unless the program copies them deliberately. Keeping outer and inner objects separate makes both aliases and shallow copies predictable before debugging begins.

Pause and reflect

In your own words, note what you understood, what remains unclear, or what you want to revisit. The note stays with this lesson.

0 of 3 exercises marked done

Review

Not marked done.