Строка изменяемый объект python

Изменяемые и неизменяемый типы объектов#

Программисту C/C++ может показаться, что во второй строке увеличивается на 1 значение, хранящееся в созданном на первой строке целочисленном объекте. На самом деле это не так: создаётся новый объект, хранящий результат вычисления выражения a + 1 , а затем имя a связывается с этим новым объектом. Чтобы продемонстрировать это, напечатаем идентификатор объекта до и после увеличения на 1.

a = 0 print(a, id(a)) a += 1 print(a, id(a)) 
0 2835673868560 1 2835673868592

Видим, что идентификатор меняет свое значение, а значит имя a ссылается на разные объекты до и после инструкции a += 1 .

В python все типы объектов можно разделить на два вида: изменяемые ( mutable ) и неизменяемые ( immutable ).

  • Значение, хранящееся в объекте неизменяемого типа, невозможно изменить никакими способами. Единственный способ получить объект такого типа с другим значением — создать новый объект с нужным значением.
  • Значение, хранящееся в объекте изменяемого типа, можно изменить не создавая новый объект. Изменения объекта возможно за счет вызова его методов или применения к нему операторов.

Все встроенные числовые типы ( bool , int , float , complex , ( decimal , fractions , которые также присутствуют в стандартной библиотеке, но обсуждаться здесь не будут)) являются неизменяемыми. Единственный изменяемый тип объектов, с которым мы уже сталкивались — list . Продемонстрируем его изменяемость.

Оператор “ += ” определен и для списков, только с другим эффектом: он расширяет список слева от него, элементами итерируемого объекта справа.

l = [42] print(l, id(l)) l += "abc" print(l, id(l)) 
[42] 1384847112704 [42, 'a', 'b', 'c'] 1384847112704

Для неизменяемого объекта a выражение a += b эквивалентно выражению a = a + b .

Разделяемый ссылки#

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

Разделяемые ссылки на неизменяемый объект#

Создадим две ссылки a и b на один и тот же объект целочисленного типа.

Во второй строке создаётся имя b и оно связывается с объектом, на которое указывает имя a . Убедиться, что имена указывают на один и тот же объект, можно сравнив их адреса ( id(a) == id(b) ). В python помимо оператора сравнения на равенство “ == ”, ещё есть оператор сравнения на идентичность is , который по сути дела сравнивает ссылки на объекты.

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

Читайте также:  ajax.html

Источник

Изменяемые и неизменяемые типы данных в Python

Python считается одним из самых удивительных языков программирования. Многие люди выбирают его в качестве первого языка из-за его элегантности и простоты. Благодаря широкому сообществу, избытку пакетов и согласованности синтаксиса, опытные профессионалы также используют Python. Тем не менее, существует одна вещь, которая раздражает как новичков, так и некоторых профессиональных разработчиков – объекты Python.

Изменяемые и неизменяемые объекты

Как известно, объектом в Python является абсолютно все, а каждый объект относится к какому-либо типу данных. Типы данных бывают изменяемые и неизменяемые (англ. mutable и immutable). К неизменяемым относятся целые числа (int), числа с плавающей запятой (float), булевы значения (bool), строки (str), кортежи (tuple). К изменяемым — списки (list), множества (set), байтовые массивы (byte arrays) и словари (dict).

Функции id() и type()

Разобраться с изменяемостью типов данных нам помогут встроенные функции и операторы Python.

Встроенный метод id() возвращает идентификатор объекта в виде целого числа. Это целое число обычно относится к месту хранения объекта в памяти. Встроенная функция type() возвращает тип объекта.

Что касается операторов, для определения идентичности переменных мы можем использовать == , а is используется для определения того, указывают ли переменные на один и тот же объект. Почитать подробнее об отличиях этих операторов можно здесь.

Если сравнить две переменные, x и y , имеющие одинаковое значение, при помощи оператора равенства ( x == y ), он выдаст True. Но если мы при помощи того же оператора сравним идентификаторы объектов x и y (полученные с использованием функции id() ) – мы получим False. Дело в том, что во втором случае мы сравнивали адреса памяти переменных, а они разные – расположены в разных местах. Хотя значения, которые содержат эти переменные, одинаковы.

x = 'Привет!' y = 'Привет!' x == y # Получим True id(x) == id(y) # Получим False

Создадим переменную z путем присвоения ей в качестве значения переменной x . Используя оператор is , мы обнаружим, что обе переменные указывают на один и тот же объект и, соответственно, имеют одинаковые идентификаторы.

x = 'Привет!' z = x x is z # Получим True id(x) == id(z) # Получим True

Неизменяемые типы данных

Давайте рассмотрим некоторые неизменяемые типы.

Целые числа (int)

Давайте определим переменную x , имеющую значение 10. Встроенный метод id() используется для определения местоположения x в памяти, а type() используется для определения типа переменной. Когда мы пытаемся изменить значение x , оно успешно изменяется.

Читайте также:  Kotlin ios and android

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

x = 10 print(x, type(x), id(x)) # Получим (10, int, 140727505991744)
x = 12 print(x, type(x), id(x)) # Получим (12, int, 140727505991808)

Строки (str)

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

В данном примере мы определили строковую переменную x , но допустили ошибку в слове и теперь хотим исправить «ю» на «и». Однако мы получаем TypeError. Это показывает, что строковые объекты не подлежат обновлению.

x = 'Прювет!' x[2] = 'и' # Получим TypeError: 'str' object does not support item assignment

Кортежи (tuple)

Давайте разберем кортежи. Мы определили кортеж с 4 значениями. Воспользуемся функцией id() для вывода его адреса. Если мы захотим изменить значение первого элемента, то получим ошибку TypeError. Это означает, что кортеж не поддерживает присвоение или обновление элементов.

tuple1 = (1, 2, 3, 4) print(tuple1, id(tuple1)) # Получим (1, 2, 3, 4) 3240603720336

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

tuple1 = (5, 6, 7, 8) print(tuple1, id(tuple1)) # Получим (5, 6, 7, 8) 3240603720256

Числа с плавающей запятой (float)

У нас есть переменная x типа float. Используя функцию id() , мы можем узнать ее адрес. Если мы попробуем заменить элемент с индексом 1, то получим TypeError. Как и в предыдущих примерах видим, что float не поддерживает модификацию элемента.

x = 3.456 x[1] = 4 # Получим TypeError: 'float' object does not support item assignment

Если же мы обновим float, переопределив его, то при вызове получим новое значение и новый адрес.

x = 3.654 type(x), id(x) # Получим (float, 3240603166960)

Изменяемые типы данных

Теперь давайте рассмотрим некоторые изменяемые типы.

Списки (list)

Определим список с именем x и добавим в него некоторые значения. После этого обновим список: присвоим новое значение элементу с индексом 1. Можем заметить, что операция успешно выполнилась.

x = ['Яблоко', 'Груша', 'Слива'] x[1] = 'Ананас' x # выведет ['Яблоко', 'Ананас', 'Слива']

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

Читайте также:  Twisted and python 3

Создадим новое имя y и свяжем его с тем же объектом списка. А теперь проверим, совпадает ли x с y . Нам вернется True. Кроме того, x и y имеют одинаковые адреса памяти.

x = y = ['Яблоко', 'Груша', 'Слива'] x is y # True id(x), id(y), id(x) == id(y) # (3240602862208, 3240602862208, True)

Теперь добавим новое значение к списку x и проверим обновленный вывод.

x.append('Персик') x # ['Яблоко', 'Груша', 'Слива', 'Персик']

Если мы теперь вызовем y , то получим тот же список, что и при вызове x . Хотя непосредственно в y мы ничего не добавляли. Это означает, что по сути мы обновляем один список объектов, у которого есть два разных имени: x и y . Оба они одинаковы и имеют один адрес в памяти даже после модификации.

y # ['Яблоко', 'Груша', 'Слива', 'Персик'] x is y, id(x) == id(y) # (True, True)

Словари (dict)

Словари — часто используемый тип данных в Python. Давайте посмотрим на их изменчивость.

Определим словарь под именем dict с тремя ключами и их значениями. Когда мы распечатаем его, отобразится все его содержимое. Можно распечатать каждое значение словаря отдельно, а также использовать ключи вместо индексов. Подробнее о добавлении элементов в словарь вы можете узнать тут.

dict = dict # Получим dict['Name'], dict['Age'], dict['Job'] # ('Алиса', 27, 'Senior Python Developer')

Давайте изменим какое-нибудь значение в нашем словаре. Например, обновим значение для ключа Name . Выведем обновленный словарь. Значение изменилось. При этом сами ключи словаря неизменяемы.

Списки и кортежи: наглядный пример изменяемых и неизменяемых объектов

Давайте по отдельности определим список и кортеж. Убедимся, что в кортеже есть значение типа список, а в списке есть значение типа кортеж.

tuple1 = ([1, 1], 2, 3) list1 = [(1, 1), 2, 3] tuple1, list1 # (([1, 1], 2, 3), [(1, 1), 2, 3])

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

tuple1[0][0] = 'Поменялся' tuple1 # (['Поменялся', 1], 2, 3)

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

list1[0][0] = 'Поменялся' list1 # Получим TypeError: 'tuple' object does not support item assignment

Заключение

Мы разобрали различия между изменяемым и неизменяемым объектами в Python. Стоит понимать, что всё в Python называется объектами. И главное различие между ними – являются они изменяемыми или неизменяемыми.

Источник

Оцените статью