If `L1_copy = L1` copies nothing, why does mutating one name change the other — and what does that mean inside a function?
Short drills on what this video just taught. Write the code, run the checks, and reveal the answer only if you are stuck.
You're given nums = [10, 20, 30, 40]. Build a genuine clone of it and assign that to clone, then build an alias of it and assign that to alias.
(Vocabulary: is tests whether two names point at one and the same object. The slice that duplicates an entire list is a pair of square brackets with a single colon inside.)
Walking the copy while removing from the original
Write L1_copy = L1[:] above for e in L1_copy: if e in L2: L1.remove(e), and trace it on L1 = [10, 20, 30, 40] and L2 = [10, 20, 50, 60] to [30, 40].
Assignment on a mutable object
Write L1_copy = L1, draw the single object carrying two names, and record the result the same loop now leaves in L1, alongside the Boston and Beantown naming analogy.
Formal parameters as aliases for actual parameters
Record that calling remove_duplicates(La, Lb) binds L1 and La to one object with the same id(), and print La after the call to show the mutation.