Какой термин описывает это свойство работы списков? - PullRequest
1 голос
/ 20 марта 2012

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

>>> x = 5
>>> l = [x]
>>> x += 1
>>> l
[5]
>>> x
6

Как называется список, который делает список с переменной x, чтобы предотвратить привязку его к каким-либо изменениям исходного значения x? Экранирование? Общая структура? Привязка списка? Ничего не возвращается из поиска Google с использованием этих терминов.

Вот пример с более подробной информацией (но, к сожалению, у него нет определения).

an example of list structure sharing

Кредит ocw.mit.edu

Ответы [ 5 ]

5 голосов
/ 20 марта 2012

Как называется список, который делает список с переменной x, чтобы предотвратить привязку к каким-либо изменениям исходного значения x? Экранирование? Общая структура? Привязка списка? Ничего не возвращается из поиска Google с использованием этих терминов.

Поскольку список не ничего не делает и не является свойством коллекций.

В Python переменные - это имена.

>>> x = 5

Это означает: x должно быть именем для значения 5.

>>> l = [x]

Это означает: l должно быть именем для значения, которое получается в результате взятия значения, которое x names (5), и создания списка из одного элемента с этим значением ([5]).

>>> x += 1

x += 1 здесь переписывается в x = x + 1, потому что целые числа неизменны. Вы не можете заставить значение 5 увеличиваться на 1, потому что тогда оно будет 5 больше.

Таким образом, это означает: x перестанет быть именем для того, что он в данный момент называет, и начнет называться значением для значения, которое следует из математического выражения x + 1. Т.е. 6.

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


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

>>> x = 5

Теперь это означает: x - это метка для фрагмента памяти, который содержит представление числа 5.

>>> l = [x]

Теперь это означает: l - это метка для фрагмента памяти, который содержит некоторую структуру списка (возможно, включая некоторые указатели и тому подобное), который будет каким-либо образом инициализирован, так что он представляет список с 1 элементом, что имеет значение 5 (скопировано из переменной x). Нельзя заставить логически содержать x, поскольку это отдельная переменная, и у нас есть семантика значений; поэтому мы храним копию.

>>> x += 1

Теперь это означает: увеличить число в переменной x; сейчас это 6. Список, опять же, не затронут.

Независимо от вашей семантики, вы не можете таким образом влиять на содержимое списка. Ожидать, что содержимое списка изменится, означает, что он не соответствует вашим интерпретациям. (Это становится более очевидным, если переписать код на l = [5]; x = l[0]; x += 1.)

4 голосов
/ 20 марта 2012

Я бы назвал это «неизменяемостью» содержащегося объекта.

Я думаю, вы сравниваете свою ситуацию со следующей:

x = []
l = [x]
x += [1]
print l # --> [[1]]

Разница:

В этой ситуации (изменяемая ситуация) вы изменяете свой исходный объект x, который содержится в списке l.

Однако в вашей ситуации у вас есть x точка для неизменяемого объекта (5), который затем добавляется в список.После этого эта ссылка заменяется на 6, но только для x, а не для списка.

Так что x += <something> либо изменяет x, либо заменяет его другим объектом в зависимости отприрода типа объекта.


РЕДАКТИРОВАТЬ: Это также не имеет ничего общего с природой списков.Вы можете добиться того же с 2 переменными:

x = 5
y = x
print x, y, x is y
x += 1
print x, y, x is y

против

x = []
y = x
print x, y, x is y
x += [1]
print x, y, x is y

Первая изменится x из-за неизменности int с, в результате x is y ложно, а во втором x is y остается истинным, потому что объект (список) видоизменен и идентичность объекта, на который ссылаются x и y, остается прежней.

1 голос
/ 20 марта 2012

Поведение, которое вы описываете, связано с ссылками .Если вы знакомы с c, вы, вероятно, также знакомы с «указателями».Указатели в c могут усложнить * , а Python использует модель данных, которая значительно упрощает работу.Но наличие некоторого опыта в c помогает понять поведение Python здесь, которое тесно связано с поведением c указателей.Таким образом, «указатель», «ссылка» и «разыменование» - это все термины, которые относятся к тому, о чем вы говорите, хотя ни один из них не является для него вполне «именем».Возможно, лучшее название для этого - «косвенность» - хотя это слишком абстрактно и инклюзивно;это очень специфический тип косвенного обращения.Возможно "ссылочная семантика"?Вот слайд из выступления самого GvR, который использует этот термин, и поиск в Google выдает несколько полезных обращений.

Но если у вас нетлюбой фон в c, вот мое лучшее объяснение.Короче говоря, вы можете рассматривать имя Python как указатель на объект.Поэтому, когда вы присваиваете имя значению, вы «указываете» это имя на значение.Затем, когда вы назначаете новое значение имени, вы указываете на новое значение;но в результате старое значение не изменяется вообще.Это кажется естественным, если думать об именах как об указателях;«значение имени» изменяется, а «значение значения» - нет.

Немного смущает то, что += ведет себя непоследовательно.Когда вы используете += для числа, результат имеет смысл, используя приведенную выше метафору:

x = 5
y = x
x += 1
print x, y 
# 6 5

Поведение точно такое же, как если бы вы сделали x = x + 1.

Но иногда += перегружается так, что происходит мутация на месте.Это прагматичная, но немного противоречивая идиома:

x = [5]
y = x
x += [6]
print x, y
# [5, 6] [5, 6]

Итак, здесь «значение значения» равно .На самом деле это не самая любимая вещь в Python, но для этого есть веские причины.

1 голос
/ 20 марта 2012

Единственное, что list делает с x в вашем примере, это читает;он никак не взаимодействует с переменной.Фактически список , сгенерированный выражением [x], вообще не взаимодействует с переменной x.

Если бы вам пришлось ввести для него часть жаргона, это было бызахват значения или, возможно, просто независимость .

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

0 голосов
/ 20 марта 2012

То, что вы фактически делаете, - это создание списка с одним элементом, который ссылается на того же объекта, что и x.Затем вы привязываете новое значение к x, в то время как список все еще ссылается на старый элемент.Это потому, что += возвращает ссылку на новый объект (6) и оставляет старый 5 объект без изменений.Целые числа неизменны в Python.

...