Насколько я понимаю, строки Python неизменяемы.
Я пробовал следующий код:
a = "Dog"
b = "eats"
c = "treats"
print a, b, c
# Dog eats treats
print a + " " + b + " " + c
# Dog eats treats
print a
# Dog
a = a + " " + b + " " + c
print a
# Dog eats treats
# !!!
Разве Python не должен был препятствовать этому назначению? Я, наверное, что-то упускаю.
Любая идея?
python
string
immutability
mutability
Джейсон
источник
источник
id()
функцию.a
будет иметь другой идентификатор до и после назначения, что указывает на то, что он указывает на разные объекты. Точно так же с кодом, которыйb = a
вы обнаружите,a
иb
будет иметь тот же идентификатор, что означает, что они ссылаются на один и тот же объект.Ответы:
Сначала
a
указал на строку «Собака». Затем вы изменили переменную,a
указав новую строку «Собака ест угощения». На самом деле вы не изменили строку «Dog». Строки неизменяемы, переменные могут указывать на все, что угодно.источник
Сами строковые объекты неизменяемы.
Переменная,
a
указывающая на строку, изменяема.Рассматривать:
источник
a.append(3)
- это не то же самое, чтоa = a + 3
. Это даже неa += 3
(дополнение на месте эквивалентно.extend
, а не.append
).+
ведет себя одинаково для списков и строк - он объединяется путем создания новой копии и не изменяет ни один из операндов.append
функции, потому что они неизменяемы.Переменная a указывает на объект «Собака». Лучше думать о переменной в Python как о теге. Вы можете перемещать тег к другим объектам, что вы и сделали, когда перешли
a = "dog"
наa = "dog eats treats"
.Однако неизменность относится к объекту, а не к тегу.
Если вы пытались
a[1] = 'z'
сделать"dog"
в"dzg"
, вы получите ошибку:потому что строки не поддерживают назначение элементов, поэтому они неизменяемы.
источник
Что-то изменчиво только тогда, когда мы можем изменить значения, хранящиеся в ячейке памяти, без изменения самой ячейки памяти.
Уловка заключается в следующем: если вы обнаружите, что ячейки памяти до и после изменения совпадают, они могут быть изменены.
Например, список изменяемый. Как?
Строка неизменна. Как мы это докажем?
мы получили
Итак, нам не удалось изменить строку. Это означает, что строка неизменна.
При переназначении вы изменяете переменную, чтобы она указывала на само новое местоположение. Здесь вы не изменили строку, а изменили саму переменную. Вот что вы делаете.
id
до и после переназначения различаются, поэтому это доказывает, что вы на самом деле не мутируете, а указываете переменную на новое место. Это не изменяет эту строку, а изменяет эту переменную.источник
Переменная - это просто метка, указывающая на объект. Объект неизменен, но вы можете сделать так, чтобы метка указывала на совершенно другой объект, если хотите.
источник
Рассматривать:
Обратите внимание, что шестнадцатеричное расположение памяти не изменилось, когда я дважды сохранил одно и то же значение в переменной. Это изменилось, когда я сохранил другое значение. Строка неизменна. Не из-за фанатизма, а потому, что вы платите за производительность, создавая новый объект в памяти. Переменная
a
- это просто метка, указывающая на этот адрес памяти. Его можно изменить, чтобы указать на что угодно.источник
Заявление
a = a + " " + b + " " + c
можно разбить на основе указателей.a + " "
говорит, дайте мнеa
точки, которые нельзя изменить, и добавьте" "
к моему текущему рабочему набору.объем памяти:
+ b
говорит: дайте мнеb
точки, которые нельзя изменить, и добавьте их в текущий рабочий набор.объем памяти:
+ " " + c
говорит добавить" "
в текущий набор. Затем дайте мнеc
точки, на которые нельзя изменить, и добавьте их в текущий рабочий набор. объем памяти:Наконец,
a =
говорит , что мой указатель указывает на результирующий набор.объем памяти:
"Dog"
восстанавливается, потому что указатели больше не подключаются к этому фрагменту памяти. Мы никогда не изменяли раздел памяти,"Dog"
в котором находился, что и подразумевается под неизменным. Однако мы можем изменить, какие метки, если они есть, указывают на этот раздел памяти.источник
источник
Есть разница между данными и меткой, с которой они связаны. Например, когда вы делаете
данные
"dog"
создаются и помещаются под меткуa
. Метка может измениться, но то, что находится в памяти, не изменится. Данные"dog"
будут все еще существовать в памяти (пока сборщик мусора не удалит их) после того, как вы выполнитеВ вашей программе
a
теперь ^ указывает на ^,"cat"
но строка"dog"
не изменилась.источник
Строки Python неизменяемы. Однако
a
это не строка: это переменная со строковым значением. Вы не можете изменить строку, но можете изменить значение переменной на новую строку.источник
Переменные могут указывать куда угодно .. Если вы выполните следующие действия, будет выдана ошибка:
источник
Строковые объекты Python неизменяемы. Пример:
В этом примере мы видим, что когда мы присваиваем другое значение, оно не изменяется. Создается новый объект.
И это нельзя изменить. Пример:
Произошла ошибка.
источник
«изменяемый» означает, что мы можем изменить содержимое строки, «неизменяемый» означает, что мы не можем добавить дополнительную строку.
источник
>>> a = 'dogs'
>>> a.replace('dogs', 'dogs eat treats')
'dogs eat treats'
>>> print a
'dogs'
Неизменный, не правда ли ?!
Часть изменения переменной уже обсуждалась.
источник
replace()
метод возвращает новую строку.Рассмотрим это дополнение к вашему примеру
Одно из наиболее точных объяснений, которые я нашел в блоге:
Ссылка на блог: https://jeffknupp.com/blog/2012/11/13/is-python-callbyvalue-or-callbyreference-neither/
источник
Добавляем немного больше к вышеупомянутым ответам.
id
переменной изменяется при переназначении.Это означает, что мы изменили переменную,
a
чтобы она указывала на новую строку. Теперь существует дваstring
(str) объекта:'initial_string'
сid
= 139982120425648и
'new_string'
сid
= 139982120425776Рассмотрим приведенный ниже код:
Теперь
b
указывает на'initial_string'
и имеет то же самое,id
чтоa
и до переназначения.Таким образом,
'intial_string'
не был изменен.источник
Резюмируя:
Не неизменный:
Неизменный:
Это ошибка Python 3, потому что она неизменяема. И это не ошибка в Python 2, потому что очевидно, что он не является неизменным.
источник
Встроенная функция
id()
возвращает идентификатор объекта в виде целого числа. Это целое число обычно соответствует положению объекта в памяти.Первоначально 'a' хранится в ячейке памяти 139831803293008, так как строковый объект является неизменяемым в python, если вы попытаетесь изменить и переназначить ссылку, будет удалена и будет указателем на новую ячейку памяти (139831803293120).
источник
источник
Это изображение дает ответ. Пожалуйста, прочтите это.
источник
Мы просто объединяем два строковых значения. Мы никогда не меняем значение (а). Только что (а) представляют другой блок памяти, который имеет значение "dogdog". Потому что в бэкэнде одна переменная никогда не представляет два блока памяти одновременно. Значение (а) перед конкатенацией было «собака». Но после этого (а) представляют "собаку", потому что теперь (а) в backend rep. блок со значением "dogdog". А «собака» - это респ. by (b) и «собака» не считается значением мусора, пока (b) не представляет «собаку».
Путаница в том, что мы представляем блоки памяти (содержащие данные или информацию) в бэкэнде с тем же именем переменной.
источник
Вы можете сделать массив numpy неизменяемым и использовать первый элемент:
затем:
или
источник