Reputation: 5300
a = [1,2,3,4,5]
b = a[1]
print id(a[1],b) # out put shows same id.hence both represent same object.
del a[1] # deleting a[1],both a[1],b have same id,hence both are aliases
print a # output: [1,3,4,5]
print b # output: 2
Both b,a[1] have same id but deleting one isn't effecting the other.Python reference states that 'del' on a subscription deletes the actual object,not the name object binding
. Output: [1,3,4,5] proves this statement.But how is it possible that 'b' remains unaffected when both a[0]
and b
have same id.
Edit: The part 'del' on a subscription deletes the actual object,not the name object binding
is not true.The reverse is true. 'del' actually removes the name,object bindings.In case of 'del' on subscription (eg. del a[1]) removes object 2 from the list object and also removes the current a[1]
binding to 2
and makes a[1]
bind to 3
instead. Subsequent indexes follow the pattern.
Upvotes: 4
Views: 995
Reputation: 375925
They have the same id
because Python reuses the id
for small integers, even if you delete these... This is mentioned in the docs:
The current implementation keeps an array of integer objects for all integers between -5 and 256, when you create an int in that range you actually just get back a reference to the existing object.
We can see this behaviour:
>>> c = 256
>>> id(c)
140700180101352
>>> del c
>>> d = 256
>>> id(d)
140700180101352 # same as id(c) was
>>> e = 257
>>> id(e)
140700180460152
>>> del e
>>> f = 257
>>> id(f)
140700180460128 # different to id(e) !
Upvotes: 0
Reputation: 71610
del
doesn't delete objects, it deletes references.
There is an object which is the integer value 2
. That one single object was referred to by two places; a[1]
and b
.
You deleted a[1]
, so that reference was gone. But that has no effect on the object 2
, only on the reference that was in a[1]
. So the reference accessible through the name b
still reaches the object 2
just fine.
Even if you del
all the references, that has no effect on the object. Python is a garbage collected language, so it is responsible for noticing when an object is no longer referenced anywhere at all, so that it can reclaim the memory occupied by the object. That will happen some time after the object is no longer reachable.1
1 CPython uses reference counting to implement it's garbage collection2, which allows us to say that objects will usually be reclaimed as soon as their last reference dies, but that's an implementation detail not part of the language specification. You don't have to understand exactly how Python collects its garbage and shouldn't write programs that depend on it; other Python implementations such as Jython, PyPy, and IronPython do not implement garbage collection this way.
2 Plus an additional garbage collection mechanism to detect cyclic garbage, which reference counting can't handle.
Upvotes: 8
Reputation: 32597
There are multiple issues at work here. First, calling del
on a list member removes the item from the list, which releases the reference count on the object, but it will not deallocate it since the variable b
still reference it. You can never deallocate something which you have a reference to.
The second issue to note here is that integer numbers close to zero are actually pooled and are never deallocated. You should normally not have to bother knowing about this though.
Upvotes: 2
Reputation: 142256
del
merely decrements the reference count for that object. So at after b = a[1]
the object at a[1]
has 2 (let's say) references. After delete a[1], it is gone from the list
and now only has 1 reference, as it's still referenced by b
. No actual deletion occurs until the ref. count is 0, and then only on a GC cycle.
Upvotes: 6