Понимание оператора "is" Python




The is оператор не соответствует значениям переменных, но
сами экземпляры.




что это значит?



я объявил две переменные с именем x и y присвоение одинаковых значений в обеих переменных, но он возвращает false, когда я использую is оператора.



мне нужно уточнение. Вот мой код.



x = [1, 2, 3]
y = [1, 2, 3]

print x is y #It prints false!
583   9  

9 ответов:

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

из документации is оператор:

операторы is и is not тест на идентичность объекта:x is y true если и только если 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)
True

Ref;
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

    Ничего не найдено.