Periodically delete long dicts / lists in Python good practice?

python

Solution

`del` is not equivalent to free(3). It doesn't force Python to free memory. It may not end up freeing memory at all. You should avoid associating it with memory usage entirely.

The only thing `del` does is delete a name from its scope. (Or delete an item from a collection, or delete an attribute. But I assume that's not what you're talking about here.)

Effectively, this:

del foo

Is equivalent to this:

del LOCAL_SCOPE['foo']

So this doesn't free any memory:

massive_list = list(range(1000000))
same_massive_list = massive_list
del massive_list

...because all it does is remove the name `massive_list`. The underlying object still has another name, `same_massive_list`, so it doesn't go away. `del` isn't a secret hook for controlling Python's memory management; it's just one of several ways to ask Python to invoke its memory management.

(By the way, CPython is refcounted + cycle-collected, not garbage-collected. Objects are immediately freed as soon as the last reference to them disappears. Garbage does not lie around waiting to be cleaned up. Of course, other implementations do different things; PyPy, for example, is garbage collected.)

Now, if the name you use is the only name for the list/dict/whatever, then `del` will certainly cause its refcount to drop to zero, so it'll be freed. But, since `del`'s semantics are really about removing names, I wouldn't use it in this case. I'd just let the variable drop out of scope (if practical), or reassign the name to a blank list, or `None`, or whatever makes sense for your program. You can even empty the list in-place, which will work even if there are several names for the same list:

foo = list(range(1000000))
bar = foo
foo[:] = []
# Both `bar` and `foo` still refer to the original list, but now it's empty

You can do the same thing to a dict with `d.clear()`.

The only place I'd use `del` on a name is in a class or module scope, where I temporarily need some helper value but really really don't want to expose it as part of the API. This is really rare, but it's the only case I've run into where I actually want the semantics of "remove this name".

Problem

I have been writing a long script that occasionally builds large dicts and/or lists, and I was wondering if performance could be improved by deleting them with `del` when I'm finished using them. Or is it normal practice to leave these objects hanging around to be taken care of by garbage collection? What is the best practice here? Thanks.

Original source