is
Оператор не совпадают со значениями переменных, но сами экземпляры.
Что это на самом деле значит?
Я объявил две переменные с именами x
и y
присвоил одинаковые значения обеим переменным, но он возвращает false, когда я использую is
оператор.
Мне нужно разъяснение. Вот мой код.
x = [1, 2, 3]
y = [1, 2, 3]
print(x is y) # It prints false!
Ответы:
Вы неправильно поняли, что
is
тестирует оператор. Он проверяет, указывают ли две переменные на один и тот же объект , а не имеют ли две переменные одинаковое значение.Из документации для
is
оператора :==
Вместо этого используйте оператор:Это печатает
True
.x
иy
представляют собой два отдельных списка:Если вы воспользуетесь
id()
функцией, вы увидите этоx
иy
получите разные идентификаторы:но если вы должны были назначить
y
наx
то обе точки к тому же объекту:и
is
показывает, что оба являются одним и тем же объектом, он возвращаетсяTrue
.Помните, что в Python имена - это просто метки, ссылающиеся на значения ; у вас может быть несколько имен, указывающих на один и тот же объект.
is
сообщает вам, указывают ли два имени на один и тот же объект.==
сообщает вам, относятся ли два имени к объектам с одинаковым значением.источник
A is B
то же самое, что иid(A) == id(B)
.id(A)
переменную, а позже ожидаете,variable == id(B)
что она все еще будет работать; если онA
был удален за это время, емуB
можно было бы присвоить то же место в памяти.\n
>>> y = 5\n
>>> x is y\n
True\n
>>> x == y\n
True\n
>>>\n
Другой дубликат спрашивал, почему две равные строки обычно не идентичны, на что здесь нет ответа:
Итак, почему это не одна и та же строка? Особенно с учетом этого:
Отложим на время вторую часть. Как первое могло быть правдой?
Интерпретатор должен иметь «таблицу интернирования», таблицу, отображающую строковые значения для строковых объектов, поэтому каждый раз, когда вы пытаетесь создать новую строку с содержимым
'abc'
, вы получаете тот же объект. В Википедии есть более подробное обсуждение того, как работает интернирование.А в Python есть таблица интернирования строк; вы можете вручную интернировать строки с помощью
sys.intern
метода.На самом деле, Python будет разрешено автоматически стажер любого неизменных типов, но не требуется , чтобы сделать это. Различные реализации будут использовать разные значения.
CPython (реализация, которую вы используете, если вы не знаете, какую реализацию вы используете) автоматически обрабатывает небольшие целые числа и некоторые специальные синглтоны, такие как
False
, но не строки (или большие целые числа, или маленькие кортежи, или что-то еще). Вы можете легко это увидеть:Хорошо, но почему были
z
иw
идентичны?Это не интерпретатор автоматически интернирует, это значения сворачивания компилятора.
Если же во время компиляции строка появляется дважды в одном модуле (что именно это означает, трудно определить, что это не то же самое , как строковый литерал, потому что
r'abc'
,'abc'
и'a' 'b' 'c'
все разные литералы , но та же строка, но легко понять , интуитивно) компилятор создаст только один экземпляр строки с двумя ссылками.Фактически, компилятор может пойти еще дальше: он
'ab' + 'c'
может быть преобразован'abc'
оптимизатором, и в этом случае он может быть свернут вместе с'abc'
константой в том же модуле.Опять же, Python это разрешено, но не обязательно. Но в этом случае CPython всегда сворачивает небольшие строки (а также, например, небольшие кортежи). (Хотя компилятор команд интерактивного интерпретатора не выполняет ту же оптимизацию, что и компилятор «модуль за раз», поэтому вы не увидите точно таких же результатов в интерактивном режиме.)
Итак, что вы должны делать с этим как программист?
Ну… ничего. У вас почти никогда не будет причин беспокоиться об идентичности двух неизменяемых значений. Если вы хотите знать, когда можно использовать
a is b
вместоa == b
, вы задаете неправильный вопрос. Просто используйте всегда,a == b
кроме двух случаев:x is None
.x
повлияет ли изменение наy
.источник
w
иz
идентичны из-за значений сворачивания компилятора, почему это также работает в REPL, даже используяid()
для проверки ссылок? Использование REPL на Python 3.7is
возвращает истину, только если они на самом деле один и тот же объект. Если бы они были такими же, изменение одного также проявилось бы в другом. Вот пример разницы.источник
Эта аналогия, вызванная повторяющимся вопросом , может сработать:
источник
is
иis not
являются двумя операторами идентичности в Python.is
Оператор не сравнивает значения переменных, а сравнивает идентичности переменных. Учти это:В приведенном выше примере показано, что идентификатор (также может быть адресом памяти в Cpython) различен для обоих
a
иb
(хотя их значения одинаковы). Вот почему, когда вы говорите, чтоa is b
он возвращает false из-за несоответствия идентификаторов обоих операндов. Однако, когда вы говоритеa == b
, он возвращает истину, потому что==
операция проверяет только то, имеют ли оба операнда одинаковое значение, назначенное им.Интересный пример (для выпускника):
В приведенном выше примере, хотя
a
и возвращеныb
две разные переменные . Это связано с тем, что тип is является неизменяемым объектом. Итак, python (я думаю, чтобы сэкономить память) выделил тот же объект, когда он был создан с тем же значением. Итак, в этом случае идентичности переменных совпали и оказались совпадающими .a is b
True
a
int
b
a is b
True
Это будет применяться ко всем неизменяемым объектам:
Надеюсь, это поможет.
источник
-5
или выше, чем256
в Python, будет False. Python кеширует числа в диапазоне [-5, 256].x is y
то же самоеid(x) == id(y)
, что сравнивать идентичность объектов.Как отметил @ tomasz-kurgan в комментарии ниже,
is
оператор необычно ведет себя с некоторыми объектами.Например
Ref;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24
источник
Как вы можете проверить здесь на небольшие целые числа. Числа выше 257 - это не маленькие целые числа, поэтому они рассчитываются как другой объект.
В
==
этом случае лучше использовать .Дополнительная информация здесь: http://docs.python.org/2/c-api/int.html
источник
X указывает на массив, Y указывает на другой массив. Эти массивы идентичны, но
is
оператор будет смотреть на эти указатели, которые не идентичны.источник
is
оператора это показывает.id
если вы этого не попросите.Он сравнивает идентичность объекта, то есть, ссылаются ли переменные на один и тот же объект в памяти. Это как
==
в Java или C (при сравнении указателей).источник
Простой пример с фруктами
Вывод:
Если вы попытаетесь
Вывод другой:
Это потому, что оператор == сравнивает только содержимое переменной. Для сравнения идентичностей двух переменных используйте is оператор
Чтобы распечатать идентификационный номер:
источник
is
Оператор не что иное, как версия английский язык==
. Поскольку идентификаторы двух списков разные, ответ неверен. Можешь попробовать:* Потому что идентификаторы обоих списков будут одинаковыми
источник
is
не является «английской версией==
»