Использование оператора is для сравнения двух строковых фрагментов в python - PullRequest
4 голосов
/ 18 июня 2020

Я экспериментировал с нарезкой строк в python, и это мой код:

s = 'a string'
print(id(s[3:]), id(s[5:]))
print(id(s[3:])==id(s[5:]))
print(s[3:] is s[5:])
print(s[3:] is s[3:])

Код дал следующие результаты:

4396519216 4396519216
True
False
False

Мой вопрос в том, как эти фрагменты строки хранятся в памяти, почему разные фрагменты строки имеют один и тот же идентификатор и с одним и тем же идентификатором, почему они дают значение «False» при сравнении с использованием ключевого слова «is»?

Ответы [ 2 ]

9 голосов
/ 18 июня 2020

Поскольку вы не сохраняете срезы в переменной (или где-либо еще) после вызова id, их время жизни фактически не перекрывается, поэтому id можно использовать повторно.
из * Документы 1005 * :

Возвращает «идентичность» объекта. Это целое число, которое гарантированно будет уникальным и постоянным для этого объекта в течение его времени жизни. Два объекта с неперекрывающимся временем жизни могут иметь одинаковое значение id ().

обратите внимание, что, поскольку is нуждается в них обоих для жизни, они, вероятно, получают разные идентификаторы, но когда вы вызываете id для каждого из них по отдельности, он может быть уничтожен после возврата id, а само сравнение выполняется для int, возвращаемого функцией.

, если вы сохраняете их в фиктивные переменные, вы получите результаты, которые, на мой взгляд, менее удивительны:

s = 'a string'
s3 = s[3:]
s5 = s[5:]
print(id(s3), id(s5))
print(id(s3)==id(s5))
print(s3 is s5)
print(s3 is s3)

Вывод:

25517664 25517728
False
False
True
1 голос
/ 18 июня 2020

Синтаксис == сравнивает значения объектов String. Технически он запускает метод __eq__ для объекта String.

Синтаксис is сравнивает объекты, а не значения объектов. Когда вы берете кусок строки, вы создаете новый объект

>>> print(id(s[3:]))
139911809265200
>>> print(id(s[3:]))
139911809262384

Что-то странное происходит со значениями, возвращаемыми из функции id, чего я не понимаю. Однако эта проблема id - отдельная вещь, которая не влияет на работу синтаксиса == и is

>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200, 139911809265200)
>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809262384, 139911809262384, 139911809262384, 139911809262384)
>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200, 139911809265200)
>>> (id(s[3:]), id(s[3:]), id(s[3:]), id(s[3:]))
(139911809262384, 139911809262384, 139911809262384, 139911809262384)

>>> a = id(s[3:])
>>> id(a)
139911809261520
>>> b = id(s[3:])
>>> id(b)
139911809261424
>>> c = id(s[3:])
>>> id(c)
139911809261360


>>> (id(a), id(b), id(c))
(139911809261520, 139911809261424, 139911809261360)
>>> (id(a), id(b), id(c))
(139911809261520, 139911809261424, 139911809261360)
>>> (id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200)
>>> (id(s[3:]), id(s[3:]), id(s[3:]))
(139911809263472, 139911809263472, 139911809263472)
>>> (id(s[3:]), id(s[3:]), id(s[3:]))
(139911809265200, 139911809265200, 139911809265200)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...