40

Inspired by this question.

Why is there no list.clear() method in python? I've found several questions here that say the correct way to do it is one of the following, but no one has said why there isn't just a method for it.

del lst[:]
lst[:] = []

While it may go against the "zen of python" to have more than one way of doing something, it certainly seems more obvious to me to have a "list.clear()" method. It would also fall in line with dicts and sets, both of which have .clear().

I came across a few posts to the python-dev and python-ideas concerning this and didn't come to a definitive answer (see here (2006) and here (2009)). Has Guido weighed in on it? Is it just a point of contention that hasn't been resolved yet over the last 4-5 years?

Update: list.clear() was added to python in 3.3 - see here

braX
  • 11,506
  • 5
  • 20
  • 33
job
  • 9,003
  • 7
  • 41
  • 50
  • 20
    That's ridiculous, of course there's a value in knowing why. It's insight into how the language was designed and provides a deeper understanding of python. For a language that claims to be as user friendly and intuitive as python, I was surprised it wasn't there. If there was a good reason, I couldn't think of one off the top of my head. – job Sep 10 '09 at 12:37

4 Answers4

18

In the threads you linked Raymond Hettinger pretty much sums up the pros and cons of adding that method. When it comes to language design, it's really important to be conservative. See for example the "every feature starts with -100 points" principle the C# team has. You don't get something as clean as Python by adding features willy-nilly. Just take a look at some of the more cruftier popular scripting languages to see where it takes you.

I guess the .clear() method just never did cross the implicit -100 points rule to become something worth adding to the core language. Although given that the methodname is already used for an equivalent purpose and the alternative can be hard to find, it probably isn't all that far from it.

mgilson
  • 300,191
  • 65
  • 633
  • 696
Ants Aasma
  • 53,288
  • 15
  • 90
  • 97
  • +1: There's no sensible use case for clearing a list when you have garbage collection that works. – S.Lott Sep 10 '09 at 02:31
  • 18
    Note that this has now "crossed the -100 points rule", and `list.clear()` was added in Python 3.3 -- see [@Jacek's answer](http://stackoverflow.com/a/6675045/68707). – Ben Hoyt Jan 07 '13 at 20:16
  • 1
    @S.Lott How about when you have a subclassed `list` that has a helper method (say to load from a db) that needs to remove all the items? – Tom Apr 02 '13 at 03:14
  • The link to Raymond's email is actually https://mail.python.org/pipermail/python-list/2006-April/384992.html and the discussion as a whole can be found at https://mail.python.org/pipermail/python-list/2006-April/thread.html#356236 – MartyMacGyver Feb 16 '16 at 21:05
  • Links are dead :( – wim Nov 13 '20 at 01:19
15

While there was no list.clear() when this question was asked, 3.3 now has one (as requested in http://bugs.python.org/issue10516). Additionally, clear() methods have been added to bytearray and MutableSequence to ease switching between lists and other collections (set, dict etc).

Full details of the change can be found here.

Tharwen
  • 3,057
  • 2
  • 24
  • 36
Jacek Sieka
  • 603
  • 6
  • 13
7

I can't answer to the why; but there absolutely should be one, so different types of objects can be cleared with the same interface.

An obvious, simple example:

def process_and_clear_requests(reqs):
    for r in reqs:
        do_req(r)
    reqs.clear()

This only requires that the object support iteration, and that it support clear(). If lists had a clear() method, this could accept a list or set equally. Instead, since sets and lists have a different API for deleting their contents, that doesn't work; you end up with an unnecessarily ugly hack, like:

def process_and_clear_requests(reqs):
    for r in reqs:
        do_req(r)
    if getattr(reqs, "clear"):
        reqs.clear()
    else:
        del reqs[:]

As far as I'm concerned, using del obj[:] or obj[:] = [] are just unpleasant, unintuitive hacks to work around the fact that list is missing clear().

This is taking "reducing redundancy" to a fault, where it damages the consistency of the language, which is even more important.

As to which you should use, I'd recommend del obj[:]. I think it's easier to implement for non-list-like objects.

Glenn Maynard
  • 55,829
  • 10
  • 121
  • 131
  • Good points about having consistent interfaces. I was going to suggest that you use pop() in your example (I know it's just an example), but `pop()` only serves to highlight interface inconsistency! – mhawke Sep 10 '09 at 00:29
  • I had removed this note for brevity, but: set's "add" and list's "append" should also have had the same name, for similar reasons. Oh well; all languages have their warts. – Glenn Maynard Sep 10 '09 at 00:56
-11

The question should be why clear was deemed necessary in the first place. The following works to clear any Python collection that I can think of.

def clear(x):
    return type(x)()

>>> s = {1, 2, 3}
>>> s
set([1, 2, 3])
>>> s = clear(s)
>>> s
set([])
>>> l = [1, 2, 3]
>>> l
[1, 2, 3]
>>> l = clear(l)
>>> l
[]
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • 4
    That doesn't clear an object -- it makes a new object of the appropriate type which is empty. The original object is still full, and any references it contains are still live. Or am I missing something obvious? – DSM Dec 05 '12 at 00:01
  • @DSM, OK I'll admit that this doesn't work in all cases, for example when the object has been passed into a function and you're trying to mutate the original. Other than that, anything contained should go away when the original container is garbage collected. – Mark Ransom Dec 05 '12 at 00:04
  • 2
    This method should more aptly be named "new" instead of "clear". – MrWonderful Nov 24 '14 at 18:59