Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling 'del' on a list

Tags:

python

list

del

class ToBeDeleted:
    def __init__(self, value):
        self.value = val

    # Whatever...

    def __del__(self):
        print self.value

l = [ToBeDeleted(i) for i in range(3)]
del l

This prints 2, 1, 0.


  • Now, is the order of the deleted elements defined somewhere in specification or is it implementation-specific? (or maybe I don't understand the underlying mechanics)

  • Could the output, for example, be 0, 1, 2? I realize the 2, 1, 0 order is probably done to avoid the memory reallocations for the elements while deleting them, but still the question remains.

  • And the last one - what's the difference between del l and del l[:] statements?

like image 791
Yippie-Ki-Yay Avatar asked Nov 20 '11 22:11

Yippie-Ki-Yay


3 Answers

Running del l will remove any reference to the list, so the symbol l will be gone. In contrast, running del l[:] removes the contents of the list, leaving l as an empty list.

The __del__ method is what runs when the last reference to an instance is being destroyed.

The order of deletion isn't specified and is implementation specific. When you run del l, the only thing that is guaranteed is that the reference count for the list l and each of its elements will decrease by one.

With pypy, nothing else will happen until the garbage collector is run. The order of the object removal depends on the order that GC visits the objects.

In cpython, the OP was correct in observing that reference decrementing occurs right-to-left. When invoking del l[:] here is the code used to decrement the refcounts: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l700 . When del l is invoked, similar code is used to decrement the refcounts: http://hg.python.org/cpython/file/2.7/Objects/listobject.c#l596

like image 156
Raymond Hettinger Avatar answered Sep 29 '22 07:09

Raymond Hettinger


Others have already answered. I'll just add what I found in CPython sources.

The list_dealloc function in listobject.c file contains this comment immediately before looping over list items to decrement their reference counts:

    /* Do it backwards, for Christian Tismer.
       There's a simple test case where somehow this reduces
       thrashing when a *very* large list is created and
       immediately deleted. */
like image 34
yak Avatar answered Sep 29 '22 08:09

yak


  • Deletion order is implementation-specific.
  • Per the answer to the first point, yes it could delete it in some other order (even elements first, random, whatever), and avoiding reallocations has little to do with it. It's just a matter of how the implementation chooses to walk the children. Perhaps the memory allocator is happier if the order of freeing reverses the order of allocating; but that's just a guess.
  • del l deletes the variable itself (and thus the list, if nothing else holds it), whereas del l[:] removes all the elements from the list. Try del l; print l.
like image 25
Marcelo Cantos Avatar answered Sep 29 '22 08:09

Marcelo Cantos