The repeated-row trap and changing a list in a loop
Assigning a list or dictionary to another name does not copy it; both names point at the same object. A shallow copy makes a new outer container that still shares the inner objects, and a deep copy duplicates everything all the way down.
Change the code and press Run (Ctrl+Enter). Predict what will happen first, then break it on purpose and read what changes. Your edits are saved and match the lesson page.
Ready for more? This phase has 6 hands-on exercises with automatic checks.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Make a = [1, 2, 3]. Create b as a real copy (not an alias), append 4 to b, and print both lists.
Make data = {"tags": ["a", "b"]}. Make a deep copy, append "c" to the copy's tags, and print both to prove they are independent.
Build a 2-row, 3-column grid of zeros correctly, set the first cell of the first row to 5, and print it.
Explain it without notes
What happens when you write b = a for a list, and how do you get a separate list?
What is the difference between a shallow copy and a deep copy?
Why does [[0] * 3] * 3 behave surprisingly, and how do you fix it?
Why is it a bug to remove items from a list inside for item in that_list?
After b = a, what is the difference between a += [3] and a = a + [3] for lists, and why does it matter?
Expected output
bad grid: [[1, 0, 0], [1, 0, 0], [1, 0, 0]]
good grid: [[1, 0, 0], [0, 0, 0], [0, 0, 0]]
loop and remove: [4, 8]
loop over a copy: [9]
comprehension: [9]