Если кортеж является неизменным, то почему он может содержать изменяемые элементы?
Кажется противоречием то, что когда изменяемый элемент, такой как список, действительно изменяется, кортеж, к которому он принадлежит, остается неизменным.
источник
Если кортеж является неизменным, то почему он может содержать изменяемые элементы?
Кажется противоречием то, что когда изменяемый элемент, такой как список, действительно изменяется, кортеж, к которому он принадлежит, остается неизменным.
Это отличный вопрос.
Основная идея заключается в том, что кортежи не могут знать, являются ли объекты внутри них изменчивыми. Единственное, что делает объект изменчивым, - это наличие метода, который изменяет его данные. В общем, нет способа обнаружить это.
Другое понимание состоит в том, что контейнеры Python на самом деле ничего не содержат. Вместо этого они хранят ссылки на другие объекты. Аналогично, переменные Python не похожи на переменные в скомпилированных языках; вместо этого имена переменных - это просто ключи в словаре пространства имен, где они связаны с соответствующим объектом. Нед Батчелдер хорошо объясняет это в своем блоге . В любом случае, объекты знают только свой счетчик ссылок; они не знают, что это за ссылки (переменные, контейнеры или внутренние компоненты Python).
Вместе эти две идеи объясняют вашу загадку (почему неизменный кортеж, «содержащий» список, кажется, изменяется при изменении базового списка). Фактически, кортеж не изменился (он по-прежнему имеет те же ссылки на другие объекты, что и раньше). Кортеж не мог измениться (потому что у него не было методов мутации). Когда список изменился, кортеж не получил уведомление об изменении (список не знает, ссылается ли он на переменную, кортеж или другой список).
Пока мы находимся на этой теме, вот несколько других мыслей, которые помогут вам завершить вашу ментальную модель того, что такое кортежи, как они работают, и их предполагаемое использование:
Кортежи характеризуются в меньшей степени своей неизменностью, а в большей степени - их назначением.
Кортежи - это способ Python собирать разнородную информацию под одной крышей. Например,
s = ('www.python.org', 80)
объединяет строку и число, чтобы пара хост / порт могла передаваться как сокет, составной объект. С этой точки зрения вполне разумно иметь изменяемые компоненты.
Неизменность идет рука об руку с другим свойством, хешабильностью . Но hashability не является абсолютным свойством. Если один из компонентов кортежа не может быть хэшируемым, то и весь кортеж не может быть хэшируемым. Например, t = ('red', [10, 20, 30])
не может быть хэшируемым.
Последний пример показывает 2-кортеж, который содержит строку и список. Сам кортеж не является изменяемым (т. Е. У него нет методов для изменения его содержимого). Аналогично, строка является неизменной, потому что строки не имеют никаких методов мутации. У объекта списка есть методы мутации, поэтому его можно изменить. Это показывает, что изменчивость является свойством типа объекта - некоторые объекты имеют методы мутации, а некоторые - нет. Это не меняется только потому, что объекты вложены.
Помните две вещи. Во-первых, неизменность - это не волшебство, а просто отсутствие методов мутации. Во-вторых, объекты не знают, какие переменные или контейнеры ссылаются на них - они знают только количество ссылок.
Надеюсь, это было полезно для вас :-)
hash()
потому что все, что наследуется от объекта () является хэшируемым, и поэтому подклассы должны явно отключить хеширование. 2) Hashibility не гарантирует неизменность - легко создать примеры изменяемых объектов. 3) Кортежи, как и большинство контейнеров в Python, просто имеют ссылки на базовый объект - они не обязаны проверять их и делать выводы о них.Это потому, что кортежи не содержат списков, строк или чисел. Они содержат ссылки на другие объекты . 1 Невозможность изменить последовательность ссылок, содержащихся в кортеже, не означает, что вы не можете изменить объекты, связанные с этими ссылками. 2
1. Объекты, значения и типы (см .: абзацы от второго до последнего)
2. Стандартная иерархия типов (см .: «Неизменяемые последовательности»)
источник
Прежде всего, слово «неизменный» может означать много разных вещей для разных людей. Мне особенно нравится, как Эрик Липперт классифицировал неизменность в своем блоге . Там он перечисляет такие виды неизменности:
Их можно комбинировать различными способами, чтобы сделать еще больше видов неизменности, и я уверен, что их будет больше. Вид неизменности, который вас интересует, представляет собой глубокую (также известную как переходная) неизменность, в которой неизменяемые объекты могут содержать только другие неизменные объекты.
Ключевым моментом этого является то, что глубокая неизменность является лишь одним из многих, многих видов неизменности. Вы можете принять тот тип, который предпочитаете, если вы знаете, что ваше понятие «неизменного», вероятно, отличается от чьего-либо другого понятия «неизменного».
источник
Насколько я понимаю, этот вопрос необходимо перефразировать как вопрос о проектных решениях: почему разработчики Python решили создать тип неизменяемой последовательности, который может содержать изменяемые объекты?
Для того, чтобы ответить на этот вопрос, мы должны думать о цели кортежи служить: они служат в качестве быстрого , общего назначения последовательности. Имея это в виду, становится совершенно очевидно, почему кортежи являются неизменяемыми, но могут содержать изменяемые объекты. Для остроумия:
Кортежи быстры и эффективны с точки зрения памяти: кортежи создаются быстрее, чем списки, потому что они неизменяемы. Неизменяемость означает, что кортежи можно создавать как константы и загружать как таковые, используя постоянное свертывание . Это также означает, что они быстрее и эффективнее для создания памяти, потому что нет необходимости в перераспределении и т. Д. Они немного медленнее, чем списки для произвольного доступа к элементам, но быстрее для распаковки (по крайней мере, на моем компьютере). Если бы кортежи были изменяемыми, они бы не были такими быстрыми для таких целей, как эти.
Кортежи общего назначения : кортежи должны содержать любой объект. Они привыкли (быстро) делать такие вещи, как списки аргументов переменной длины (через
*
оператор в определениях функций). Если кортежи не могут содержать изменяемые объекты, они будут бесполезны для подобных вещей. Python должен был бы использовать списки, которые, вероятно, замедляли бы работу и, конечно, были бы менее эффективными в использовании памяти.Итак, вы видите, что для выполнения своей цели кортежи должны быть неизменяемыми, но также должны иметь возможность содержать изменяемые объекты. Если бы разработчики Python хотели создать неизменяемый объект, который гарантирует, что все объекты, которые он «содержит», также являются неизменяемыми, им пришлось бы создать третий тип последовательности. Усиление не стоит дополнительной сложности.
источник
Вы не можете изменить
id
его элементы. Так что он всегда будет содержать одни и те же предметы.источник
Здесь я остановлюсь на конечности и скажу, что важная часть здесь заключается в том, что, хотя вы можете изменить содержимое списка или состояние объекта, содержащегося в кортеже, вы не можете изменить то, что объект или список есть. Если бы у вас было что-то, что зависело от того, что [3] было списком, даже если оно пустое, я мог бы посчитать это полезным.
источник
Одна из причин заключается в том, что в Python нет общего способа преобразовать изменяемый тип в неизменяемый (см. Отклоненный PEP 351 и связанную с ним дискуссию почему он был отклонен). Таким образом, было бы невозможно помещать различные типы объектов в кортежи, если бы у него было это ограничение, включая практически любой созданный пользователем объект без хэша.
Единственная причина, по которой словари и наборы имеют это ограничение, заключается в том, что они требуют, чтобы объекты были хэшируемыми, поскольку они реализованы внутри как хеш-таблицы. Но обратите внимание , что, по иронии судьбы, словари и сами наборы не неизменны (или hashable). Кортежи не используют хэш объекта, поэтому его изменчивость не имеет значения.
источник
Кортеж является неизменным в том смысле, что сам кортеж не может расширяться или сжиматься, а не то, что все содержащиеся в нем элементы являются неизменяемыми. В противном случае кортежи скучны.
источник