Почему в python нет метода list.clear ()? - PullRequest
39 голосов
/ 10 сентября 2009

Вдохновлен этим вопросом.

Почему в python нет метода list.clear ()? Я нашел здесь несколько вопросов, в которых говорится, что правильный способ сделать это - один из следующих, но никто не сказал, почему для этого нет только одного метода.

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

Хотя может показаться, что «дзен питона» может иметь более чем один способ что-то сделать, для меня, безусловно, более очевидно иметь метод list.clear (). Это также соответствовало бы указаниям и наборам, оба из которых имеют .clear ().

Я натолкнулся на несколько сообщений об идеях python-dev и python, касающихся этого, и не нашел однозначного ответа (см. здесь (2006) и здесь ( 2009)). Взвешивал ли это Гвидо? Это просто предмет спора, который еще не решен за последние 4-5 лет?

Обновление: list.clear () был добавлен в python в версии 3.3 - см. Здесь

Ответы [ 5 ]

18 голосов
/ 10 сентября 2009

В связанных темах Раймонд Хеттингер в значительной степени подводит итог плюсов и минусов добавления этого метода. Когда дело доходит до языкового дизайна, очень важно быть консервативным. См., Например, «каждая функция начинается с -100 баллов» принцип, который имеет команда C #. Вы не можете получить что-то такое же чистое, как Python, добавляя новые функции. Достаточно взглянуть на некоторые из более жестких популярных языков сценариев, чтобы понять, куда это вас приведет.

Я полагаю, что метод .clear() просто никогда не пересекал неявное правило -100 баллов, чтобы стать чем-то, что стоит добавить в основной язык. Несмотря на то, что имя метода уже используется для эквивалентной цели, и найти альтернативу может быть сложно, вероятно, это не так уж далеко от него.

14 голосов
/ 13 июля 2011

Пока не было list.clear(), когда задавался этот вопрос, 3.3 теперь имеет один (как было запрошено в http://bugs.python.org/issue10516).. Кроме того, clear() методы были добавлены к bytearray и MutableSequence для облегчения переключения между списками и другими коллекциями (набор, дикт и т. Д.).

Полную информацию об изменении можно найти здесь .

7 голосов
/ 10 сентября 2009

Я не могу ответить на почему; но он обязательно должен быть один, поэтому разные типы объектов могут быть очищены с помощью одного и того же интерфейса.

Очевидный простой пример:

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

Для этого требуется только, чтобы объект поддерживал итерацию и чтобы он поддерживал clear (). Если бы у списков был метод clear (), он мог бы принять список или установить его одинаково. Вместо этого, поскольку наборы и списки имеют разные API для удаления их содержимого, это не работает; в итоге вы получите излишне уродливый хак, как:

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

Насколько мне известно, использование del obj [:] или obj [:] = [] - просто неприятные, не интуитивно понятные способы обойти тот факт, что в списке отсутствует clear ().

Это сводит «сокращение избыточности» к ошибке, когда она нарушает согласованность языка, что еще более важно.

Что вы должны использовать, я бы порекомендовал del obj [:]. Я думаю, что это легче реализовать для объектов, не похожих на список.

0 голосов
/ 05 декабря 2014

При тестировании часто полезно настроить данные, образующие область тестов, в глобальные переменные, чтобы тесты могли основываться друг на друге, если это необходимо / проще. В таких случаях наличие метода для очистки списка позволит вам сделать это без необходимости объявлять эти переменные как глобальные в функции (то есть в тестах). Я знаю, тесты не должны зависеть друг от друга ...

0 голосов
/ 05 декабря 2012

Вопрос должен заключаться в том, почему clear был сочтен необходимым в первую очередь. Следующее работает, чтобы очистить любую коллекцию Python, о которой я могу думать.

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
[]
...