Consider the following case, which is a small version of what you are trying to understand:
def foo(x):
x = []
x.append(1)
print(x)
my_list = []
foo(my_list)
print(my_list)
You expect the function foo
to clear the list it received as an argument and, afterward, modify it by appending the number 1
, right? Actually, that is not what happens...
>>> foo(my_list)
[1]
>>> print(my_list)
[]
Why so?
Because when you wrote x = []
, instead of clearing the original list, you actually changed the local variable x
to refer to a new list. On the other hand, my_list
is still referring to the original list!
Now, let's try the same but using x[:]
instead:
def foo(x):
x[:] = []
x.append(1)
print(x)
my_list = []
foo(my_list)
print(my_list)
Now, everything should work as you expected:
>>> foo(my_list)
[1]
>>> print(my_list)
[1]
The x[:]
trick is basically telling the interpreter to replace the contents of the list referred by x
by a new empty list. Now, it is not x
that will change to which list it is pointing to. In fact, it will still refer to the same list as my_list
and, as a side effect, this will alter the original list.
In order to truly grasp what is going on behind the scenes, take a look at how variables are passed by assignment in Python, specially if you aren't familiar with the concept of pointers.