Почему сравнение строк с использованием '==' или 'is' иногда дает другой результат? - PullRequest
1030 голосов
/ 01 октября 2009

У меня есть программа на Python, в которой двум переменным присвоено значение 'public'. В условном выражении у меня есть сравнение var1 is var2, которое не удается, но если я изменяю его на var1 == var2, оно возвращает True.

Теперь, если я открою свой интерпретатор Python и выполнил то же самое сравнение "is", это будет успешно.

>>> s1 = 'public'
>>> s2 = 'public'
>>> s2 is s1
True

Что мне здесь не хватает?

Ответы [ 14 ]

10 голосов
/ 08 августа 2014

Я отвечаю на вопрос, несмотря на то, что вопрос старый, потому что ни один из ответов выше не цитирует ссылку на язык

На самом деле оператор is проверяет идентичность и == оператор проверяет равенство,

Из справочника по языку:

Типы влияют практически на все аспекты поведения объекта. Даже важность идентичности объекта зависит в некотором смысле: для неизменяемых типов операции , которые вычисляют новые значения, могут фактически возвращать ссылку на любой существующий объект с тем же типом и значением, в то время как для изменяемых объектов это недопустимо . Например, после а = 1; b = 1, a и b могут или не могут ссылаться на один и тот же объект со значением один, в зависимости от реализации, но после c = []; d = [], c и d гарантированно ссылаются на два разных, уникальных, недавно созданных пустых списка. (Обратите внимание, что c = d = [] назначает один и тот же объект как c, так и d.)

Таким образом, из приведенного выше утверждения мы можем сделать вывод, что строки, являющиеся неизменяемым типом, могут потерпеть неудачу при проверке с помощью «is» и могут быть успешными при проверке с помощью «is»

То же самое относится к int, кортежу, который также является неизменяемым типом

6 голосов
/ 05 июля 2017

Эквивалентность значения теста оператора ==. Оператор is проверяет идентичность объекта, Python проверяет, действительно ли оба объекта являются одним и тем же объектом (т. Е. Живут ли они по одному адресу в памяти).

>>> a = 'banana'
>>> b = 'banana'
>>> a is b 
True

В этом примере Python создал только один строковый объект, и оба a и b ссылаются на него. Причина в том, что Python внутренне кэширует и повторно использует некоторые строки в качестве оптимизации, на самом деле в памяти есть просто строка «банан», совместно используемая a и b; Чтобы вызвать нормальное поведение, вам нужно использовать более длинные строки:

>>> a = 'a longer banana'
>>> b = 'a longer banana'
>>> a == b, a is b
(True, False)

Когда вы создаете два списка, вы получаете два объекта:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> a is b
False

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

Если a относится к объекту и вы присваиваете b = a, тогда обе переменные ссылаются на один и тот же объект:

>>> a = [1, 2, 3]
>>> b = a
>>> b is a
True
2 голосов
/ 14 сентября 2017

is будет сравнивать ячейку памяти. Используется для сравнения на уровне объекта.

== будет сравнивать переменные в программе. Используется для проверки на уровне значения.

is проверка на эквивалентность на уровне адреса

== проверяет эквивалентность на уровне значений

2 голосов
/ 24 апреля 2017

is - тестирование идентичности, == - тестирование на равенство (см. Документация Python ).

В большинстве случаев, если a is b, то a == b. Но есть исключения, например:

>>> nan = float('nan')
>>> nan is nan
True
>>> nan == nan
False

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

...