добавить приложение обновить и расширить в Python - PullRequest
4 голосов
/ 06 июля 2010

Есть ли статья или обсуждение на форуме или что-то еще, где объясняется, почему списки используют добавление / расширение, а наборы и диктанты используют добавление / обновление.

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

Необходимость конвертировать между ними возникает регулярно, когда мы повторяем разработку. Со временем, когда структура программы трансформируется, различные структуры приобретают и теряют такие требования, как порядок и дубликаты.

Например, что-то, что начинается с неупорядоченного набора элементов в списке, может выполнить требование об отсутствии дубликатов и, следовательно, должно быть преобразовано в набор.

Все такие изменения требуют поиска и изменения всех мест, где соответствующая структура добавлена ​​/ добавлена ​​и расширена / обновлена.

Так что мне любопытно увидеть оригинальную дискуссию, которая привела к выбору этого языка, к сожалению, мне не повезло, поискать его.

Ответы [ 3 ]

5 голосов
/ 06 июля 2010

append имеет популярное определение «добавить в самый конец», а extend можно читать аналогично (в нюансе, где это означает «... за пределами определенной точки»);У наборов нет ни «конца», ни какого-либо способа указать какую-либо «точку» внутри них или «на их границах» (потому что нет «границ»!), поэтому было бы крайне ошибочно предполагать, что эти операции могут быть выполнены.

x.append(y) всегда увеличивает len(x) ровно на единицу (был ли y уже в списке x или нет);для s.add(z) такое утверждение не выполняется (длина s может увеличиваться или остается прежней).Более того, в этих фрагментах y может иметь любое значение (т. Е. Операция добавления никогда не завершается неудачей [за исключением аномального случая, когда у вас заканчивается память]) - опять же, такого утверждения нетсодержит около z (который должен быть хешируемым, в противном случае операция добавления завершится ошибкой и вызовет исключение).Аналогичные различия относятся к extend против update.Использование одного и того же имени для операций с такой радикально отличной семантикой было бы очень действительно вводящим в заблуждение.

кажется пифосным просто использовать список на первом проходе и работать с производительностью наболее поздняя итерация

Производительность меньше всего!list s поддерживают дубликаты, заказы и любой тип элемента - set s гарантируют уникальность элемента, не имеют понятия о заказе и требуют доступности элемента.Нет ничего Pythonic в использовании списка (плюс глупые проверки на дубликаты и т. Д.), Чтобы обозначить набор - производительность или нет, «говорите, что вы имеете в виду!»это Питонический Путь ;-).(В таких языках, как Fortran или C, где все, что вы получаете как встроенный контейнерный тип, это массивы, вам, возможно, придется выполнять такое «ментальное отображение», если вам нужно избегать использования дополнительных библиотек; в Python неттакая необходимость).

Редактировать : ОП утверждает в комментарии, что они не знают с самого начала (например), что дубликаты запрещены в определенном алгоритме (странно, но, независимо от того, что) - они ищут безболезненный способ сделать список в наборе, как только они делают обнаруживают, что дубликаты там плохи (и я добавлю: порядок не имеет значения, элементы могут быть хэшируемыми,индексирование / нарезка ненужных и т. д.).Чтобы получить точно такой же эффект, можно было бы получить, если бы set в Python имели "синонимы" для двух рассматриваемых методов:

class somewhatlistlikeset(set):
    def append(self, x): self.add(x)
    def extend(self, x): self.update(x)

Конечно, если единственное изменение - это создание набора (которое использовалосоздание списка), код может быть гораздо более сложным для понимания, потеряв полезную ясность, поэтому использование add против append позволяет любому, читающему код, знать «локально», является ли объект множеством по сравнению со списком.... но это тоже часть вышеупомянутого "точно такого же эффекта"! -)

3 голосов
/ 06 июля 2010

set и dict неупорядочены. «Добавить» и «расширить» концептуально применимо только к упорядоченным типам.

1 голос
/ 06 июля 2010

Это написано так, чтобы раздражать вас.

Серьезно. Он спроектирован так, что один не может просто легко конвертировать одно в другое. Исторически set s основаны на dict s, поэтому два соглашения об именах разделяют. Хотя вы можете легко написать set оболочку для добавления этих методов ...

class ListlikeSet(set):
    def append(self, x):
        self.add(x)

    def extend(self, xs):
        self.update(xs)

... больший вопрос в том, почему вы конвертируете list с в set с с такой регулярностью. Они представляют собой существенно разные модели коллекции предметов; если вам приходится много конвертировать между ними, это говорит о том, что вы не очень хорошо разбираетесь в концептуальной архитектуре вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...