Reputation: 309
Let's say I have:
a = 1
b = 2
C = 'r'
my_list = [a,b,c]
Now let's say that a, b and c are unknown and I don't know their names.
If I do:
for x in my_list: del x
it doesn't work. a, b, c have not been deleted.
Can someone explain me why?
Upvotes: 0
Views: 178
Reputation: 1994
you have multiple issues here:
a = 1
b = 2
my_list = [a,b]
assigns the values 1
and 2
to the list, not the vars. You can use mutable objects to get you desire: Immutable vs Mutable types
for x in my_list:
del x
like in 1. x
is just the value from the list (e.g. 1
, 2
, 'c'
), but even worse, its a additional reference count to the memory.
Deleting it results in decreasing the counter, not deleting the value from memory, since at least one more counter is given by the original list (and in your case the vars (a,b,c
) from the beginning).
More Info: Arguments are passed by assignment
for x in my_list:
del x
contains an other problem. If you would change the code to mylist.remove(x)
, to at least remove the entrie from the list, you would also skip every second member of the list. Quick Example:
li = [1,2,3]
for x in li:
li.remove(x)
first iteration would be x = 1
. Deleting 1
from li
results in li = [2,3]
. Then the loop continous with the second position in the list: x=3
and deleting it. 2
was skipped.
This can be avoided by using a copy of the list using the [:]
operator:
for x in li[:]:
li.remove(x)
This finaly results in an empty list
Upvotes: 1
Reputation: 3462
As @Coldspeed mentions in his comment, the variable x
which you delete is not the same as the element in the list
object.
Similar behaviour will be seen if you try to assign to x
:
for x in my_list: x='bla' #does not modify anything in my_list
However, as the items are references to the same memory block, the comparison x is my_list[0]
will equate to True
in the first loop iteration.
As such, it is possible to perform operations on the list
through usage of the shared reference, for example:
for x in my_list[:]: my_list.remove(x) #results in an empty list
Care has to be taken to first create a copy of the list and iterate over these items though, as was done in the previous lines. If you are hasty and loop over the items of a dynamically changing list, you will run into some more python magic.
for x in my_list: my_list.remove(x) #the first element gets deleted, then the second element in the list, which now has length 2, is deleted.
#Final result is the list [2] remaining
Upvotes: 1