Подтвердить что ты не робот

Почему Python рассматривает кортежи, списки, наборы и словари как принципиально разные вещи?

Одна из причин, по которой я люблю Python - это выразительная мощь/уменьшенное программирование, обеспечиваемое кортежами, списками, наборами и словарями. Как только вы поймете списки и некоторые основные шаблоны, используя in и for, жизнь станет намного лучше! Питон качается.

Однако мне непонятно, почему эти конструкции обрабатываются так же, как они, и как это меняется (становится незнакомым) с течением времени. Вернувшись в Python 2.x, я мог бы привести аргумент, что все они были просто вариациями базового типа коллекции, и это было отчасти раздражающим, что некоторые неэкзотические варианты использования требуют, чтобы вы преобразовали словарь в список и обратно очередной раз. (Разве словарь не является просто списком кортежей с определенным ограничением уникальности? Разве список не является просто набором с другим видом ограничения уникальности?).

Теперь в мире 3.x все стало сложнее. Теперь есть именованные кортежи - они начинают больше походить на специальный словарь. Теперь есть упорядоченные словари, которые начинают больше походить на список. И я только что увидел рецепт заказанных наборов. Я могу представить, что это происходит и продолжается... как насчет уникальных списков и т.д.

Дзен Python говорит: "Должен быть one-- и, предпочтительно, только один --obvious способ сделать это". Мне кажется, что это изобилие типов специализированных коллекций находится в противоречии с этой заповедью Python.

Что думают хардкорные Pythonistas?

4b9b3361

Ответ 1

Эти типы данных служат для разных целей, и в идеальном мире вы можете объединить их больше. Однако в реальном мире нам необходимо иметь эффективные реализации основных коллекций и, например, при заказе добавляется штраф за выполнение.

Именованные кортежи в основном служат для того, чтобы сделать интерфейс stat() и т.д. более удобным для использования, а также может быть приятным при работе с наборами строк SQL.

Большое объединение, которое вы ищете, на самом деле существует в виде различных протоколов доступа (getitem, getattr, iter,...), которые эти типы смешивают и соответствуют их намеченным целям.

Ответ 2

tl; dr (duck-typing)

Вы правы, чтобы увидеть некоторые сходства во всех этих структурах данных. Помните, что python использует duck-typing (если он выглядит как утка и шарлатанцы, как утка, то это утка). Если вы можете использовать два объекта в одной и той же ситуации, то для ваших текущих целей и целей они могут быть одинаковым типом данных. Но вам всегда нужно иметь в виду, что если вы попытаетесь использовать их в других ситуациях, они могут больше не вести себя одинаково.

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

Mutability (можете ли вы его изменить?)

Вы можете вносить изменения в словари, списки и наборы. Кортежи не могут быть "изменены" без копирования.

  • Mutable: dict, list, set

    Неизменяемость: tuple

Python string также является неизменяемым типом. Почему мы хотим каких-то неизменяемых объектов? Я бы перефразировал этот ответ:

  • Неизменяемые объекты могут быть оптимизированы много.

  • В Python только неизменяемые хешируются (и только хешируемые объекты могут быть членами множеств или ключи в словарях).

Сравнивая это свойство, списки и кортежи кажутся "ближайшими" двумя типами данных. На высоком уровне кортеж представляет собой неизменяемую версию списка "замораживания-рамки". Это делает списки полезными для наборов данных, которые будут меняться со временем (поскольку вам не нужно копировать список для его изменения), но кортежи полезны для таких вещей, как словарные ключи (которые должны быть неизменяемыми типами).

Заказ (и примечание по абстрактным типам данных)

Словарь, такой как набор, не имеет врожденного концептуального порядка. Это отличается от списков и кортежей, которые имеют порядок. Порядок для элементов в dict или наборе абстрагируется от программиста, что означает, что если элемент A предшествует B в цикле for k in mydata, вы не должны (и не можете вообще ) полагайтесь на A перед B, когда вы начинаете вносить изменения в mydata.

  • Сохранение заказов: list, tuple

    Сохранение без порядка: dict, set

Технически, если вы повторяете более mydata дважды подряд, это будет в том же порядке, но это более удобная функция механики python и не является частью set абстрактный тип данных (математическое определение типа данных). Списки и кортежи действительно гарантируют порядок, хотя, особенно кортежи, которые неизменны.

То, что вы видите, когда итерации (если он идет как утка...)

  • Один "элемент" для каждого элемента: set, list, tuple

    Два "элемента" для каждого элемента: dict

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

Прямые ответы на ваши вопросы

Не является словарем только список кортежей с определенной уникальностью ограничение?

Нет, есть несколько отличий. Словари не имеют встроенного порядка, который отличается от списка, который делает.

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

Из-за механики словаря, где клавиши действуют как набор, вы можете искать значения в постоянное время, если у вас есть ключ. В списке кортежей (пары здесь) вам нужно будет перебирать список до тех пор, пока не найдете ключ, то есть поиск будет линейным по количеству элементов в вашем списке.

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

Это не список, а просто набор с различной уникальностью ограничение?

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

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

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

Прекрасным примером является класс Counter(). Этот специализированный словарь был полезен мне больше раз, чем я могу считать (badoom-tshhhhh!), И он спас меня от усилий по кодированию настраиваемого решения. Я бы предпочел иметь решение, которое сообщество помогает мне разрабатывать и поддерживать лучшие практические навыки python, чем то, что находится в моей папке с настраиваемыми структурами данных и используется только один или два раза в год.

Ответ 3

Прежде всего, в Python 2 были введены упорядоченные словари и именованные кортежи, но это не так.

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

Первое различие между типами коллекций - это изменчивость. tuple и frozenset являются неизменяемыми типами. Это означает, что они могут быть более эффективными, чем list или set.

Если вы хотите что-то, вы можете получить доступ случайно или по порядку, но в основном изменитесь в конце, вы хотите list. Если вы хотите что-то, что вы также можете изменить в начале, вы хотите deque.

Вы просто не можете иметь свой торт и съесть его тоже - каждая добавленная вами функция заставляет вас потерять некоторую скорость.

dict и set принципиально отличаются от lists и кортежей`. Они хранят хэш своих ключей, позволяя вам видеть, что элемент находится в них очень быстро, но требует, чтобы ключ был хешируемым. Вы не получаете такую ​​же скорость тестирования членства со связанными списками или массивами.

Когда вы переходите к OrderedDict и NamedTuple, вы говорите о подклассах встроенных типов, реализованных в Python, а не в C. Они предназначены для особых случаев, как и любой другой код стандартной библиотеки, который вы необходимо импортировать. Они не загромождают пространство имен, но приятно иметь, когда они вам нужны.

На днях вы будете кодировать, и вы скажете: "Человек, теперь я точно знаю, что они подразумевают под" Должен быть один - и желательно только один - простой способ сделать это ", a set - это то, что мне нужно для этого, я так рад, что это часть языка Python! Если бы мне пришлось использовать список, это потребовало бы навсегда." Это, когда вы поймете, почему существуют эти разные типы.

Ответ 4

Словарь индексируется ключом (на самом деле это хэш-карта); общий список кортежей не будет. Вы можете утверждать, что оба они должны быть реализованы как отношения, с возможностью добавлять индексы по своему усмотрению, но на практике оптимизированные типы для общих случаев использования являются более удобными и эффективными.

Новые специализированные коллекции добавляются, потому что они достаточно распространены, что многие люди в конечном итоге будут внедрять их, используя более базовые типы данных, а затем у вас будут обычные проблемы с переосмыслением колес (потерянные усилия, отсутствие функциональной совместимости...). И если Python просто предложил полностью общую конструкцию, мы бы получили много людей, спрашивающих "как реализовать набор с использованием отношения" и т.д.

(btw, я использую отношение в математическом или DB смысле)

Ответ 5

Все эти специализированные типы коллекций предоставляют определенные функциональные возможности, которые недостаточно или эффективно предоставляются "стандартными" типами данных списка, кортежа, dict и set.

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

Эти дополнительные типы данных, которые вы видите как комбинации или варианты основных, фактически заполняют пробелы в функциональности, оставленные основными типами данных. С практической точки зрения, если ядро ​​Python или стандартная библиотека не предоставили эти типы данных, тогда любой, кто в них нуждается, изобрел свои неэффективные версии. Они используются реже, чем базовые типы, но достаточно часто, чтобы обеспечить стандартную реализацию.

Ответ 6

Одна из вещей, которые мне нравятся на Python, - это гибкость. И это дает мне множество функциональных, эффективных и используемых типов коллекций.

И есть еще один способ сделать это - каждый тип выполняет свою собственную работу.

Ответ 7

Мир структур данных (языковой агностик) обычно может быть сведен к нескольким небольшим базовым структурам - спискам, деревьям, хэш-таблицам и графикам и т.д., а также вариантам и их комбинациям. Каждый из них имеет свою специфическую цель с точки зрения использования и реализации.

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

Я не вижу, чтобы это нарушало "Дзен Питона" в том, чтобы делать что-то в одном направлении. Хотя вы можете использовать отсортированный словарь, чтобы сделать то, что делает словарь без использования отсортированной части, вы больше нарушаете бритву Оккама и, вероятно, вызывают снижение производительности. Я вижу, что это отличается от возможности синтаксически делать вещи разными способами a la Perl.

Ответ 8

Дзен Питона говорит: "Должен быть один - и желательно только один - простой способ сделать это". Мне кажется, что это изобилие специализированных типов коллекций противоречит этому предписанию Python.

Не удаленно. Здесь есть несколько разных вещей. Мы выбираем правильный инструмент для работы. Все эти контейнеры смоделированы по многолетним проверенным, проверенным и истинным концепциям CS.

Словари не похожи на кортежи: они оптимизированы для поиска по ключевым словам. Кортеж также неизменен, что отличает его от списка (вы можете думать о нем как о чем-то вроде frozenlist). Если вы обнаружите, что перевод словарей на списки и обратно, вы почти наверняка делаете что-то неправильно; пример поможет.

Именованные кортежи существуют для удобства и на самом деле предназначены для замены простых классов, а не словарей. Закаленные словари - это всего лишь немного обертывания, чтобы запомнить порядок, в котором вещи были добавлены в словарь. И ни один из них не является новым в версии 3.x(хотя для них может быть лучше поддержка языков, я не смотрел).