Почему в Python нет метода list.clear ()?

На основе этого вопроса.

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

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

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

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

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


person job    schedule 09.09.2009    source источник
comment
Это смешно, конечно, есть смысл знать почему. Это понимание того, как был разработан язык, и более глубокое понимание Python. Я был удивлен, что языка, который утверждает, что он такой же удобный и интуитивно понятный, как Python, его там не было. Если бы на это была веская причина, я бы не мог придумать ни одной из них.   -  person job    schedule 10.09.2009


Ответы (4)


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

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

person Ants Aasma    schedule 09.09.2009
comment
+1: нет разумного варианта использования для очистки списка, когда у вас есть работающая сборка мусора. - person S.Lott; 10.09.2009
comment
Обратите внимание, что теперь это превышает правило -100 баллов, и list.clear() был добавлен в Python 3.3 - см. @ ответ Яцека. - person Ben Hoyt; 08.01.2013
comment
@ S.Lott Как насчет случая, когда у вас есть подкласс list, у которого есть вспомогательный метод (скажем, для загрузки из базы данных), который должен удалить все элементы? - person Tom; 02.04.2013
comment
Ссылка на электронную почту Раймонда на самом деле mail.python.org/pipermail. /python-list/2006-April/384992.html и обсуждение в целом можно найти по адресу mail.python.org/pipermail/python-list/2006-April/ - person MartyMacGyver; 17.02.2016
comment
Ссылки мертвы :( - person wim; 13.11.2020

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

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

person Jacek Sieka    schedule 13.07.2011

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

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

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 [:]. Я думаю, что это проще реализовать для объектов, не относящихся к спискам.

person Glenn Maynard    schedule 09.09.2009
comment
Хорошие моменты в согласованных интерфейсах. Я собирался предложить вам использовать pop () в своем примере (я знаю, что это всего лишь пример), но pop() служит только для того, чтобы подчеркнуть несогласованность интерфейса! - person mhawke; 10.09.2009
comment
Я удалил это примечание для краткости, но: set add и list также должны были иметь то же имя по тем же причинам. Ну что ж; у всех языков есть свои бородавки. - person Glenn Maynard; 10.09.2009

Вопрос должен заключаться в том, почему 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
[]
person Mark Ransom    schedule 04.12.2012
comment
Это не очищает объект - это создает новый объект соответствующего типа, который является пустым. Исходный объект все еще заполнен, и все ссылки, которые он содержит, все еще живы. Или мне не хватает чего-то очевидного? - person DSM; 05.12.2012
comment
@DSM, хорошо, я признаю, что это работает не во всех случаях, например, когда объект был передан в функцию, а вы пытаетесь изменить оригинал. Помимо этого, все, что содержится, должно исчезнуть, когда исходный контейнер будет собран сборщиком мусора. - person Mark Ransom; 05.12.2012
comment
Этот метод более уместно называть новым, а не ясным. - person MrWonderful; 24.11.2014