Две переменные в Python имеют одинаковый идентификатор, но не списки или кортежи
Две переменные в Python имеют одинаковые id
:
a = 10
b = 10
a is b
>>> True
Если взять два list
s:
a = [1, 2, 3]
b = [1, 2, 3]
a is b
>>> False
в соответствии с этой ссылкой Отправитель ответил, что ссылки на неизменяемые объекты имеют один и тот же идентификатор, а изменяемые объекты, такие как списки, имеют разные идентификаторы.
Итак, теперь, согласно его ответу, кортежи должны иметь одинаковые идентификаторы - значение:
a = (1, 2, 3)
b = (1, 2, 3)
a is b
>>> False
В идеале, поскольку кортежи не изменяются, он должен возвращать True
, но он возвращает False
!
Какое объяснение?
Ответы
Ответ 1
Неизменяемые объекты не имеют одинакового id
, и, как факт, это неверно для любого типа объектов, которые вы определяете отдельно. Каждый раз, когда вы определяете объект в Python, вы создадите новый объект с новым идентификатором.
Но есть некоторые исключения для небольших целых чисел (от -5 до 256) и небольших строк (интернированные строки со специальной длиной (обычно менее 20 символов)), которые являются одиночными и имеют одинаковый id
(фактически один объект с несколькими указателями). Вы можете проверить этот факт следующим образом:
>>> 30 is 20 + 10
True
>>>
>>> 300 is 200 + 100
False
>>> 'aa' * 2 is 'a' * 4
True
>>> 'aa' * 20 is 'a' * 40
False
И для настраиваемого объекта:
>>> class A:
... pass
...
>>> A() is A() # Every time you create an instance you'll have a new instance with new identity
False
Также обратите внимание, что оператор is
проверяет идентификатор объекта, а не значение. Если вы хотите проверить значение, которое вы должны использовать ==
:
>>> 300 == 3*100
True
И поскольку такого правила для кортежей (других типов) не существует, если вы определяете два одинаковых кортежа любого размера, они получат свои собственные идентификаторы:
>>> a = (1,)
>>> b = (1,)
>>>
>>> a is b
False
Обратите внимание, что факт одиночных целых чисел и интернированных строк верен, даже если вы определяете их в изменяемых и неизменяемых объектах:
>>> a = (100, 700, 400)
>>>
>>> b = (100, 700, 400)
>>>
>>> a[0] is b[0]
True
>>> a[1] is b[1]
False
Ответ 2
Неизменяемый !=
тот же объект. *
Постоянный объект - это просто объект, состояние которого не может быть изменено; и все. Когда новый объект будет создан, ему будет присвоен новый адрес. Таким образом, проверка того, совпадают ли адреса с is
, вернет False
.
То, что 1 is 1
или "a" is "a"
возвращает True
, связано с целым кэшированием и строкой interning, выполненный Python, поэтому не позволяйте ему смущать вас; это не связано с тем, что рассматриваемые объекты являются изменяемыми/неизменяемыми.
* Пустые неизменные объекты ссылаются на один и тот же объект, а их is
ness возвращает true, это особый случай конкретной реализации.
Ответ 3
Взгляните на этот код:
>>> a = (1, 2, 3)
>>> b = (1, 2, 3)
>>> c = a
>>> id(a)
178153080L
>>> id(b)
178098040L
>>> id(c)
178153080L
Чтобы выяснить, почему a is c
оценивается как True
, тогда как a is b
дает False
, я настоятельно рекомендую вам поэтапно выполнить фрагмент выше в Интернет-преподаватель Python. Графическое представление объектов в памяти предоставит вам более глубокое понимание этой проблемы (я прилагаю скриншот).
![введите описание изображения здесь]()