Понимание оператора "is" Python
The
isоператор не соответствует значениям переменных, но
сами экземпляры.
что это значит?
я объявил две переменные с именем x и y присвоение одинаковых значений в обеих переменных, но он возвращает false, когда я использую is оператора.
мне нужно уточнение. Вот мой код.
x = [1, 2, 3]
y = [1, 2, 3]
print x is y #It prints false!
9 ответов:
вы неправильно поняли, что за
isтесты оператора. Он проверяет, если две переменные указывают тот же объект, нет, если две переменные имеют одинаковое значение.из документации
isоператор:операторы
isиis notтест на идентичность объекта:x is ytrue если и только еслиxиyэто один и тот же объект.использовать
==оператор вместо этого:print x == yэто выводит
True.xиyдва отдельные список:x[0] = 4 print(y) # prints [1, 2, 3] print(x) == y # prints Falseесли вы используете
id()функции вы увидите, чтоxиyимеют разные идентификаторы:>>> id(x) 4401064560 >>> id(y) 4401098192но если бы вы назначили
yдоxзатем оба указывают на один и тот же объект:>>> x = y >>> id(x) 4401064560 >>> id(y) 4401064560 >>> x is y Trueи
isпоказывает, что оба являются одним и тем же объектом, он возвращаетTrue.помните, что в Python, имена - это просто метки, ссылающиеся на значения; вы можете иметь несколько имен, указывающих на один и тот же объект.
isговорит вам, что если два имени указывают на один и тот же объект.==сообщает вам, если два имени относятся к объектам, которые имеют одинаковое значение.
еще один дубликат спрашивал, почему две равные строки обычно не идентичны, что на самом деле не отвечает здесь:
>>> x = 'a' >>> x += 'bc' >>> y = 'abc' >>> x == y True >>> x is y Falseтак почему же они не одна и та же строка? Особенно учитывая это:
>>> z = 'abc' >>> w = 'abc' >>> z is w True
давайте отложим вторую часть на некоторое время. Как могло первое оказаться правдой?
переводчик должен быть в "интернирование таблица", таблица сопоставления строковых значений для объектов string, поэтому каждый раз, когда вы пытаетесь создайте новую строку с содержимым
'abc', вы получаете обратно тот же объект. Википедия имеет более подробное обсуждение того, как работает стажировка.И Python и таблица интернирования строк; вы можете вручную интернировать строки с помощью
sys.internметод.на самом деле, Python это разрешено для автоматического интернирования любых неизменяемых типов, но не требуются чтобы сделать так. Различных реализаций будут стажироваться разные ценности.
CPython (реализация, которую вы используете, если вы не знаете, какую реализацию вы используете) авто-Интерны небольшие целые числа и некоторые специальные синглеты, такие как
False, но не строки (или большие целые числа, или маленькие кортежи, или что-нибудь еще). Вы можете увидеть это довольно легко:>>> a = 0 >>> a += 1 >>> b = 1 >>> a is b True >>> a = False >>> a = not a >>> b = True a is b True >>> a = 1000 >>> a += 1 >>> b = 1001 >>> a is b False
хорошо, но почему были
zиwидентичны?это не интерпретатор автоматически интернирует, это компилятор складывание значений.
если одна и та же строка времени компиляции появляется дважды в одном модуле (что именно это означает, трудно определить-это не то же самое, что строковый литерал, потому что
r'abc','abc'и'a' 'b' 'c'все разные литералы, но одна и та же строка-но легко понять интуитивно), компилятор создаст только один экземпляр строки с двумя ссылками.на самом деле, компилятор может пойти еще дальше:
'ab' + 'c'может быть преобразован в'abc'by оптимизатор, в этом случае его можно сложить вместе с'abc'константа в том же модуле.опять же, это то, что Python-это разрешено, но не требуется. Но в этом случае CPython всегда складывает небольшие строки (а также, например, небольшие кортежи). (Хотя компилятор инструкций интерактивного интерпретатора не выполняет ту же оптимизацию, что и компилятор модуля за раз, поэтому вы не увидите точно такие же результаты интерактивно.)
Итак, что вы должны делать с этим как программист?
Ну... ничего. У вас почти никогда нет причин беспокоиться, если два неизменяемых значения идентичны. Если вы хотите знать, когда вы можете использовать
a is bвместоa == b, вы задаете неправильный вопрос. Просто всегда используйтеa == bза исключением двух случаев:
- для более удобочитаемых сравнений с одноэлементными значениями, такими как
x is None.- для изменяемых значений, когда вам нужно знать, мутирует ли
xповлияет наy.
isвозвращает true, если они на самом деле один и тот же объект. Если бы они были одинаковыми, изменение одного также проявилось бы в другом. Вот пример такой разницы.>>> x = [1, 2, 3] >>> y = [1, 2, 3] >>> print x is y False >>> z = y >>> print y is z True >>> print x is z False >>> y[0] = 5 >>> print z [5, 2, 3]
предложено дублировать вопрос эта аналогия может сработать:
# - Darling, I want some pudding! # - There is some in the fridge. pudding_to_eat = fridge_pudding pudding_to_eat is fridge_pudding # => True # - Honey, what's with all the dirty dishes? # - I wanted to eat pudding so I made some. Sorry about the mess, Darling. # - But there was already some in the fridge. pudding_to_eat = make_pudding(ingredients) pudding_to_eat is fridge_pudding # => False
isиis notявляются два оператора идентификации в Python.isоператор не сравнивает значения переменных, но сравнивает идентификаторы переменных. Рассмотрим это:>>> a = [1,2,3] >>> b = [1,2,3] >>> hex(id(a)) '0x1079b1440' >>> hex(id(b)) '0x107960878' >>> a is b False >>> a == b True >>>приведенный выше пример показывает, что идентификатор (также может быть адрес памяти в Cpython) отличается для обоих
aиb(хотя их значения одинаковы). Вот почему, когда вы говоритеa is bон возвращает false из-за несоответствия в идентификаторах оба операнда. Однако, когда вы говоритеa == b, она возвращает true, потому что==операция проверяет, только если оба операнда имеют одинаковое значение, возложенные на них.интересный пример (для дополнительной марки):
>>> del a >>> del b >>> a = 132 >>> b = 132 >>> hex(id(a)) '0x7faa2b609738' >>> hex(id(b)) '0x7faa2b609738' >>> a is b True >>> a == b True >>>в приведенном выше примере, хотя
aиbэто две разные переменные,a is bвернулсяTrue. Это потому, что типaиint, который является неизменяемым объектом. Так что python (я думаю, чтобы сохранить память) выделил тот же объект дляb, когда он был создан с тем же значением. Таким образом, в этом случае идентичности переменных совпадают иa is bоказалсяTrue.это будет применяться для всех неизменяемые объекты:
>>> del a >>> del b >>> a = "asd" >>> b = "asd" >>> hex(id(a)) '0x1079b05a8' >>> hex(id(b)) '0x1079b05a8' >>> a is b True >>> a == b True >>>надеюсь, что это поможет.
Как вы можете проверить здесь до небольших целых чисел. Числа выше 257 не являются малым ints, поэтому он вычисляется как другой объект.
лучше использовать
==вместо этого в данном случае.дополнительная информация здесь:http://docs.python.org/2/c-api/int.html
x is yтакой же, какid(x) == id(y), сравнивая идентичность объектов.как указал @tomasz-kurgan в комментарии ниже
isоператор ведет себя необычно с определенными объектами.например.
>>> class A(object): ... def foo(self): ... pass ... >>> a = A() >>> a.foo is a.foo False >>> id(a.foo) == id(a.foo) TrueRef;
https://docs.python.org/2/reference/expressions.html#is-not
https://docs.python.org/2/reference/expressions.html#id24
X указывает на массив, Y указывает на другой массив. Эти массивы идентичны, но
isоператор будет смотреть на те указатели, которые не идентичны.
Он сравнивает идентичность объекта, то есть, относятся ли переменные к одному и тому же объекту в памяти. Это как
==в Java или C (при сравнении указателей).
Comments