Why does the following code change both variables:
>>> a = []
>>> b = a
>>> a.append(9)
>>> a
[9]
>>> b
[9]
>>>
But the del
statement does not achieve the same effect?
>>> a = []
>>> b = a
>>> del(a)
>>> a
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> b
[]
>>>
The
append
method works against the actual object, whiledel
works against the reference i.e. variable name.When you do:
What you're doing is assigning the label
b
to the same object that the labela
is refering to.When you do:
You're adding
9
to the list object pointed to by botha
andb
. It's the same object, so they show the same result.When you do:
You're deleting the reference to the object, not the object itself. If it's the only reference, then the object will be garbage collected. But in your case, there's another reference -
b
- so the object continues to exist.(I already answered the question in the other question of yours, so I'm going to use it here as well, with slight modifications:)
del
does not delete objects; in fact in Python, it is not even possible to tell the interpreter/VM to remove an object from memory because Python is a garbage collected language (like Java, C#, Ruby, Haskell etc).Instead, what
del
does when called on a variable (as opposed to a dictionary key or list item) like this:is that it only removes the local (or global) variable not what it points to (every variable in Python holds a pointer/reference to its contents not the content itself). In fact, since locals and globals are stored as a dictionary under the hood (see
locals()
andglobals()
),del a
is equivalent to:(or
del globals()['a']
when applied to a global.)so if you have:
you're making a list, storing a reference to it in
a
and then copying that reference intob
without copying/touching the list object itself. Therefore these two calls affect one and the same object:(
id
returns the memory address of an object)whereas deleting
b
is in no way related to touching whatb
points to:Instead of "variables", think in terms of names and objects.
This makes an empty list object and binds the name
a
to it.This simply says that
b
is now a new name for the object named bya
. We havedel a
means that we're forgetting the namea
: it is no longer bound to an object.But that you're no longer calling that list object
a
, onlyb
, doesn't affect the object itself in any way. Objects don't care, or even know about, what names you've given them. [One semi-exception is that if an object no longer has any references, it may -- or may not, no promises -- be garbage-collected.]