You got it correct. In Python, parameters are passed by what's called reference value, which means a copy or value of the reference (or pointer if you come from a C background) is passed to the method. Think of these references/pointers as integers containing indices to locations in memory.
Since the "copy" pointer (this is how we'll refer to it from now on) is pointing to the object that the "original" pointer was pointing to, any modifications we make to the object referenced by the "copy" pointer will be reflected in the original object, because the object referenced by the "copy" pointer is the original object.
But, since we have two different references (integers) pointing to the same object in memory (original = XYZ location in memory
and copy = XYZ location in memory
), when the integral or location value itself of the copy
is changed (that is another object is assigned to copy
), the change isn't reflected in original
because copy
and original
are two separate references/pointers.
If, however, copy
was a pointer to the pointer of the object (ObjectType** copy
in C), the change would have been reflected in the original
pointer/reference too.
If we have the following program,
def mutate_list(copy):
copy = [5, 6, 7, 8]
print(original, copy)
original = [1, 2, 3, 4]
mutate_list(original)
The output will be [1, 2, 3, 4] [5, 6, 7, 8]
If we change the mutate_list
method to the following:
def mutate_list(copy):
copy.clear()
copy.append([5, 6, 7, 8])
print(original, copy)
The output would be [5, 6, 7, 8] [5, 6, 7, 8]
.