Есть ли разница между «==» и «есть»?

Мой Гугл-фу подвел меня.

Эквивалентны ли следующие два теста на равенство в Python?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

Верно ли это для объектов, экземпляры которых вы собираетесь сравнивать (например, list)?

Хорошо, вот такие ответы на мой вопрос:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

Итак, == проверяет значение, а is проверяет, являются ли они одним и тем же объектом?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
629
0
400 608
14
Перейти к ответу Данный вопрос помечен как решенный

Ответы 14

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

https://docs.python.org/library/stdtypes.html#comparisons

is тесты на идентичность == тесты на равенство

Каждому (маленькому) целочисленному значению сопоставляется одно значение, поэтому каждые 3 идентичны и равны. Это деталь реализации, а не часть спецификации языка.

Ответ принят как подходящий

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

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

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True

В вашем случае второй тест работает только потому, что Python кэширует небольшие целочисленные объекты, что является деталью реализации. Для больших целых чисел это не работает:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

То же самое верно и для строковых литералов:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

См. Также этот вопрос.

Я обнаружил, что: Выход echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - foo: False True False.

ahuigo 23.07.2018 15:38

Вы потеряли меня из-за части копирования списка операторов срезов b = a[:], поэтому я отредактировал ваш ответ, чтобы добавить комментарий. Похоже, я только что достиг порога, чтобы мои правки не проверялись до их применения, так что, надеюсь, это нормально для вас. Тем не менее, вот полезный справочник о том, как копировать списки, с которыми я столкнулся и на которые мне пришлось ссылаться, чтобы понять, что вы делаете: stackoverflow.com/a/2612815/4561887

Gabriel Staples 23.01.2019 00:14

Другой способ продемонстрировать разницу - сравнить объекты разных типов, которые, конечно, никогда не могут быть одним и тем же объектом, но все равно сравнивать равные при использовании ==. Так, например, 5.0 - это значение с плавающей запятой, а 5 - целое число. Но 5.0 == 5 все равно будет возвращать True, потому что они представляют одно и то же значение. С точки зрения производительности и типизации, is всегда проверяется интерпретатором путем сравнения адресов памяти операнда, в то время как в случае == объект должен решить, определяет ли он себя как равный чему-то еще.

Bachsau 15.06.2019 16:09

1000 is 10**3 оценивается как True в Python 3.7, поскольку 10 ** 3 - это тип int. Но 1000 is 1e3 оценивается как False, поскольку 1e3 - это тип float.

Ahmed Fasih 08.09.2019 04:13

@AhmedFasih Независимо от того, является ли 1000 is 10**3 истинным, зависит от реализации и от компилятора, предварительно оценившего выражение 10**3. x=10; 1000 is x**3 соответствует False.

chepner 27.05.2020 15:41

Ваш ответ правильный. Оператор is сравнивает идентичность двух объектов. Оператор == сравнивает значения двух объектов.

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

Вы можете контролировать поведение сравнения значений объекта, определяя метод __cmp__ или метод богатое сравнение, например __eq__.

Это полностью отличается. is проверяет идентичность объекта, а == проверяет равенство (понятие, которое зависит от типов двух операндов).

То, что is, похоже, правильно работает с маленькими целыми числами (например, 5 == 4 + 1), является счастливым совпадением. Это потому, что CPython оптимизирует хранение целых чисел в диапазоне (от -5 до 256), делая их одиночными. Это поведение полностью зависит от реализации и не гарантируется, что оно будет сохранено при любых второстепенных операциях преобразования.

Например, Python 3.5 также создает синглтоны для коротких строк, но их разрезание нарушает это поведение:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

Взгляните на вопрос о переполнении стека Оператор Python «is» неожиданно ведет себя с целыми числами..

В основном это сводится к тому, что «is» проверяет, являются ли они одним и тем же объектом, а не просто равны друг другу (числа ниже 256 являются особым случаем).

Существует простое практическое правило, которое подскажет, когда использовать == или is.

  • == предназначен для равенство ценностей. Используйте его, если хотите узнать, имеют ли два объекта одинаковое значение.
  • is предназначен для ссылочное равенство. Используйте его, если хотите узнать, относятся ли две ссылки к одному и тому же объекту.

В общем, когда вы сравниваете что-то с простым типом, вы обычно проверяете равенство ценностей, поэтому вам следует использовать ==. Например, цель вашего примера, вероятно, состоит в том, чтобы проверить, имеет ли x значение, равное 2 (==), а не то, действительно ли x ссылается на тот же объект, что и 2.


Еще кое-что на заметку: из-за того, как работает эталонная реализация CPython, вы получите неожиданные и противоречивые результаты, если по ошибке используете is для сравнения эталонного равенства целых чисел:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

Это в значительной степени то, что мы ожидали: a и b имеют одинаковое значение, но являются разными объектами. Но как насчет этого?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

Это несовместимо с предыдущим результатом. Что тут происходит? Оказывается, эталонная реализация Python кэширует целочисленные объекты в диапазоне -5..256 как одноэлементные экземпляры из соображений производительности. Вот пример, демонстрирующий это:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

Это еще одна очевидная причина не использовать is: поведение остается на усмотрение реализаций, когда вы ошибочно используете его для равенства значений.

Что касается первого примера a=500 и b=500, просто хотел указать, что если вы установите a и b на промежуточное число между [-5, 256], a is b фактически вернет True. Подробнее здесь: stackoverflow.com/q/306313/7571052

AsheKetchum 30.01.2019 21:01

@AsheKetchum, да, обратите внимание, что я написал: «Оказывается, эталонная реализация Python кэширует целочисленные объекты в диапазоне -5..256 как одноэлементные экземпляры из соображений производительности».

John Feminella 01.02.2019 00:38

Так же, как добавить сюда два моих фрагмента. Используйте is, если вы хотите проверить, является ли это одним и тем же объектом (скажем, у вас есть список городов и объектов маршрута; вы можете сравнить местоположения или просто проверить, является ли он одним и тем же городом или нет - поэтому is является более сильным сравнением здесь) . В противном случае, если вас интересуют только примитивы, обычно == будет достаточно. Это скорее простое правило, которое будет нарушено, когда дела станут тяжелыми.

shady shamus 30.10.2020 12:59

Как сказал Джон Феминелла, большую часть времени вы будете использовать == и! =, Потому что ваша цель - сравнить значения. Я просто хочу разделить на категории то, чем вы будете заниматься в остальное время:

Существует один и только один экземпляр NoneType, т.е. None не является одноэлементным. Следовательно, foo == None и foo is None означают одно и то же. Однако тест is быстрее, и по соглашению Pythonic следует использовать foo is None.

Если вы занимаетесь самоанализом или возитесь со сборкой мусора или проверяете, работает ли ваш специально созданный гаджет интернирования строк или что-то в этом роде, то у вас, вероятно, есть вариант использования foo - bar.

Истины и Ложь также (сейчас) синглтоны, но нет варианта использования для foo == True и нет варианта использования для foo is True.

Is there a difference between == and is in Python?

Да, у них есть очень важное отличие.

==: проверка на равенство - семантика такова, что эквивалентные объекты (которые не обязательно являются одним и тем же объектом) будут проверяться как равные. Как документация говорит:

The operators <, >, ==, >=, <=, and != compare the values of two objects.

is: проверка идентичности - семантика такова, что объект (хранящийся в памяти) является объект. Опять же, документация говорит:

The operators is and is not test for object identity: x is y is true if and only if x and y are the same object. Object identity is determined using the id() function. x is not y yields the inverse truth value.

Таким образом, проверка идентичности аналогична проверке совпадения идентификаторов объектов. То есть,

a is b

такой же как:

id(a) == id(b)

где id - встроенная функция, которая возвращает целое число, которое «гарантированно уникально среди одновременно существующих объектов» (см. help(id)), а a и b - любые произвольные объекты.

Другие направления использования

Вы должны использовать эти сравнения для их семантики. Используйте is для проверки идентичности и == для проверки равенства.

В общем, мы используем is для проверки личности. Обычно это полезно, когда мы проверяем объект, который должен существовать в памяти только один раз, в документации это называется «синглтоном».

Сценарии использования is включают:

  • None
  • значения перечисления (при использовании перечислений из модуля перечисления)
  • обычно модули
  • обычно объекты класса, возникающие из определений классов
  • обычно функциональные объекты, возникающие из определений функций
  • все остальное, что должно существовать в памяти только один раз (как правило, все синглтоны)
  • конкретный объект, который вам нужен по личности

Обычные варианты использования == включают:

  • числа, в том числе целые
  • струны
  • списки
  • наборы
  • словари
  • настраиваемые изменяемые объекты
  • другие встроенные неизменяемые объекты, в большинстве случаев

Общий вариант использования, опять же, для ==: объект, который вам нужен, может не быть объектом такой же, вместо этого он может быть объектом эквивалент.

PEP 8 направлений

PEP 8, официальное руководство по стилю Python для стандартной библиотеки, также упоминает два варианта использования is:

Comparisons to singletons like None should always be done with is or is not, never the equality operators.

Also, beware of writing if x when you really mean if x is not None -- e.g. when testing whether a variable or argument that defaults to None was set to some other value. The other value might have a type (such as a container) that could be false in a boolean context!

Вывод равенства из идентичности

Если is истинно, можно сделать вывод о равенстве как правило - логически, если объект является самим собой, то он должен тестироваться как эквивалентный самому себе.

В большинстве случаев эта логика верна, но она зависит от реализации специального метода __eq__. Как говорят документы,

The default behavior for equality comparison (== and !=) is based on the identity of the objects. Hence, equality comparison of instances with the same identity results in equality, and equality comparison of instances with different identities results in inequality. A motivation for this default behavior is the desire that all objects should be reflexive (i.e. x is y implies x == y).

и в интересах последовательности рекомендует:

Equality comparison should be reflexive. In other words, identical objects should compare equal:

x is y implies x == y

Мы видим, что это поведение по умолчанию для настраиваемых объектов:

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

Контрапозитив также обычно верен - если что-то оказывается не равным, обычно можно сделать вывод, что это не один и тот же объект.

Поскольку тесты на равенство могут быть настроены, этот вывод не всегда верен для всех типов.

Исключение

Заметным исключением является nan - он всегда проверяется как не равный самому себе:

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

Проверка идентичности может быть намного более быстрой проверкой, чем проверка на равенство (которая может потребовать рекурсивной проверки членов).

Но он не может быть заменен равенством, когда вы можете найти более одного объекта в качестве эквивалента.

Обратите внимание, что сравнение равенства списков и кортежей предполагает, что идентичность объектов равна (потому что это быстрая проверка). Это может привести к противоречиям, если логика непоследовательна - как в случае с nan:

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

Поучительная история:

Вопрос пытается использовать is для сравнения целых чисел. Вы не должны предполагать, что экземпляр целого числа является тем же экземпляром, что и экземпляр, полученный по другой ссылке. Эта история объясняет, почему.

У комментатора был код, основанный на том факте, что маленькие целые числа (от -5 до 256 включительно) являются одиночными числами в Python вместо проверки на равенство.

Wow, this can lead to some insidious bugs. I had some code that checked if a is b, which worked as I wanted because a and b are typically small numbers. The bug only happened today, after six months in production, because a and b were finally large enough to not be cached. – gwg

Это сработало в разработке. Возможно, он прошел некоторые юнит-тесты.

И это работало в производстве - до тех пор, пока код не проверил целое число больше 256, после чего он отказал в производстве.

Это производственный сбой, который мог быть обнаружен при проверке кода или, возможно, с помощью средства проверки стиля.

Подчеркну: не используйте is для сравнения целых чисел.

«не использовать вообще» тоже было бы хорошим правилом. Идиоматический is None является исключением, но при этом == None тоже работает ...

Jean-François Fabre 24.07.2019 09:20

@ Jean-FrançoisFabre Другое исключение: официальная документация, кажется, рекомендует использовать is для сравнения Enum.

Arthur 10.02.2020 20:30

Означает ли это, что два пользовательских класса сравниваются, например, a = Car ("новый"), B = Car ("новый"), если мы используем a == b, это равно a is b, я прав?

UniSize 06.08.2020 09:23

@UniSize Не думаю, что вы правы. Проблемы: 1. вы говорите a и B, но затем вы говорите a == b (нижний регистр) и Python чувствителен к регистру. 2. вы не говорите, должны ли a и b быть эквивалентными, но два экземпляра с одинаковыми аргументами подразумевают, что они эквивалентны, но не являются одними и теми же объектами, поэтому вы ошиблись бы в своей интерпретации. Пожалуйста, перечитайте мой ответ здесь и дайте мне знать, чего не хватает, и будьте осторожны и ясны в своем ответе.

Aaron Hall 06.08.2020 17:29

@AaronHall Мои извинения, во-первых, это опечатка. Я пересмотрел это, a = Car ("новый"), b = Car ("новый"), если мы используем a == b, это равно a is b? Я понимаю, что «is» проверяет, находятся ли два объекта в одной и той же области памяти, а a == b - это сравнение двух объектов. На основании тестирования a == b возвращает false, а a is b также возвращает false. Почему при такой же инициализации a == b вернет false?

UniSize 07.08.2020 07:38

@UniSize Вот почему я сказал "подумайте" - реализация __eq__ по умолчанию использует is, и в этом случае вы были бы правы. Большинство пользовательских реализаций (и это должно быть сделано на ранних этапах жизненного цикла определения объекта, см. Мой доклад в PyGotham на эту тему: youtu.be/iGfggZqXmB0) обычно будут иметь два отдельных экземпляра с одинаковыми аргументами для теста создания экземпляра в качестве эквивалента - в этом случае вы будете неправильный. Вы все еще не сказали, эквивалентны ли a и b предполагаемый. Если вы не можете найти вопросы и ответы по этой теме, я предлагаю вам написать новый вопрос.

Aaron Hall 07.08.2020 23:37

Стоит упомянуть, что a is b - это не обязательно, то же самое, что и id(a) == id(b), или что a и b не могут быть просто «ничем». Мое понимание is было основано на этом, и авторитетный учебник допустил ту же ошибку.

OverLordGoldDragon 07.11.2020 22:19

В чем разница между is и ==?

== и is - разные сравнения! Как уже говорили другие:

  • == сравнивает значения объектов.
  • is сравнивает ссылки на объекты.

В Python имена относятся к объектам, например, в этом случае value1 и value2 относятся к экземпляру int, хранящему значение 1000:

value1 = 1000
value2 = value1

Поскольку value2 относится к одному и тому же объекту, is и == выдаст True:

>>> value1 == value2
True
>>> value1 is value2
True

В следующем примере имена value1 и value2 относятся к разным экземплярам int, даже если оба хранят одно и то же целое число:

>>> value1 = 1000
>>> value2 = 1000

Поскольку сохраняется одно и то же значение (целое число), == будет True, поэтому его часто называют «сравнением значений». Однако is вернет False, потому что это разные объекты:

>>> value1 == value2
True
>>> value1 is value2
False

Когда какой использовать?

В целом is - намного более быстрое сравнение. Вот почему CPython кэширует (или, может быть, повторно использует был бы лучшим термином) определенные объекты, такие как маленькие целые числа, некоторые строки и т. д. Но это следует рассматривать как детали реализации, который может (даже если маловероятно) измениться в любой момент без предупреждения.

Вам следует используйте только is, если вы:

  • хотите проверить, действительно ли два объекта являются одним и тем же объектом (а не одним и тем же «значением»). Одним из примеров может быть использование ты одноэлементного объекта в качестве константы.

  • хотите сравнить значение с Python постоянный. Константы в Python:

    • None
    • True1
    • False1
    • NotImplemented
    • Ellipsis
    • __debug__
    • классы (например, int is int или int is float)
    • могут быть дополнительные константы во встроенных модулях или сторонних модулях. Например np.ma.masked из модуля NumPy)

В в остальных случаях следует использовать == для проверки равенства.

Могу ли я настроить поведение?

Есть один аспект ==, который еще не упоминался в других ответах: это часть Питоны "Модель данных". Это означает, что его поведение можно настроить с помощью метода __eq__. Например:

class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))

Это просто искусственный пример, чтобы проиллюстрировать, что метод действительно вызывается:

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

Обратите внимание, что по умолчанию (если в классе или суперклассах нет другой реализации __eq__) __eq__ использует is:

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

Поэтому на самом деле важно реализовать __eq__, если вы хотите «большего», чем просто сравнение ссылок для пользовательских классов!

С другой стороны, вы не можете настраивать проверки is. Он всегда будет сравнивать только, если у вас есть такая же ссылка.

Всегда ли эти сравнения возвращают логическое значение?

Поскольку __eq__ может быть повторно реализован или отменен, он не ограничивается возвратом True или False. мог возвращает что угодно (но в большинстве случаев должно возвращать логическое значение!).

Например, с массивами NumPy == вернет массив:

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

Но проверки is всегда возвращают True или False!


1 Как упомянул Аарон Холл в комментариях:

Как правило, вам не следует выполнять какие-либо проверки is True или is False, потому что обычно эти «проверки» используются в контексте, который неявно преобразует условие в логическое значение (например, в операторе if). Таким образом, при сравнении is Trueи неявное логическое приведение выполняет больше работы, чем просто выполнение логического преобразования, и вы ограничиваете себя логическими значениями (что не считается питоническим).

Как упоминает PEP8:

Don't compare boolean values to True or False using ==.

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

Мне придется не согласиться с вашим утверждением о сравнении «констант» с is - имена, указывающие на логические значения, следует проверять с помощью логического контекста - например, if __debug__: или if not __debug__:. Вы никогда не должны использовать if __debug__ is True: или if __debug__ == True: - кроме того, константа - это просто постоянное семантическое значение, а не одноэлемент, поэтому проверка с помощью is в этом случае семантически некорректна. Я призываю вас найти источник, подтверждающий ваши утверждения - я не думаю, что вы его найдете.

Aaron Hall 20.01.2018 05:09

@AaronHall Почему вы думаете, что константы не синглтоны? Обратите внимание, что только None, True, False и __debug__ - это то, что вы бы назвали «постоянным семантическим значением», потому что их нельзя переназначить. Но все они одиночки.

MSeifert 20.01.2018 05:37

Прочтите PEP 8 - Ctrl-F и найдите слово «хуже». - Если вы проводите модульное тестирование, вы должны использовать self.assertTrue

Aaron Hall 20.01.2018 05:44

@AaronHall В некоторых случаях вам действительно нужна проверка is True или if False (но да, они довольно редки, но если вы их выполняете, вы может выполняете их с помощью is). Поэтому их иногда использует даже CPython (например, здесь или здесь)

MSeifert 20.01.2018 05:57

Почему is True хуже == True? Может ли True is TrueКогда-либо выйти из строя? Если что-то == True более вероятно потерпит неудачу, так как __eq__ может быть заменен бессмыслицей, но не is.

OverLordGoldDragon 16.06.2020 16:43

@OverLordGoldDragon Речь идет не о неудаче, а просто о стиле (эта война скопирована из PEP8 - руководства по стилю Python). В конце концов, вам, вероятно, никогда не понадобится == True или is True (за исключением особых случаев или, возможно, в тестовом коде).

MSeifert 16.06.2020 21:09

Не согласен с «никогда не is True»; У меня было несколько случаев, когда is True явно превосходит свои альтернативы по простоте и удобочитаемости, и я видел, как он и is False использовались в основном производственном коде API. Это звучит как совет «не используйте exec», который действителен, но чрезмерно раздут («никогда»).

OverLordGoldDragon 16.06.2020 21:39

@OverLordGoldDragon В программировании нет ничего без исключения. Он также не преувеличен ... «Никогда не используйте exec или is True» - это совет, чтобы защитить читателей (включая более неопытных программистов или случайных прохожих) от самих себя. Обычно предполагается, что люди, достаточно опытные в программировании, будут знать, когда нарушать правила.

MSeifert 16.06.2020 23:58

Поскольку другие люди в этом сообщении подробно отвечают на вопрос о разнице между == и is для сравнения объектов или переменных, я бы подчеркивать в основном сравнивал is и ==для струнных, которые могут давать разные результаты, и я бы призвал программистов осторожно их использовать.

Для сравнения строк обязательно используйте == вместо is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

Из:

str is hello
str == hello

Но в приведенном ниже примере == и is получат разные результаты:

str2 = 'hello sam'
    if (str2 is 'hello sam'):
        print ('str2 is hello sam')
    if (str2 == 'hello sam'):
        print ('str2 == hello sam')

Из:

str2 == hello sam

Заключение и анализ:

Осторожно используйте is для сравнения строк. Начиная с is для сравнения объектов и поскольку в Python 3+ каждая переменная, такая как строка, интерпретируется как объект, давайте посмотрим, что произошло в приведенных выше абзацах.

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

str = 'hello'
id('hello')
> 140039832615152
id(str)
> 140039832615152

Но

str2 = 'hello sam'
id('hello sam')
> 140039832615536
id(str2)
> 140039832615792

почему "is" работает так для строк с пробелами?

Akash Gupta 06.06.2018 11:58

Согласно предыдущим ответам: кажется, что python выполняет кэширование небольших целых чисел и строк, что означает, что он использует одну и ту же ссылку на объект для вхождений строки hello в этом снимке кода, в то время как он не выполнял кеширование для 'hello sam', как есть относительно больше, чем 'hello' (т.е. он управляет различными ссылками на строку 'hello sam', и поэтому оператор 'is' возвращает false в следующем примере) Исправьте меня, если я ошибаюсь

Rida Shamasneh 19.02.2019 22:49

@AkashGupta извините за задержку с ответом. Я просто добавил еще несколько объяснений, почему это произошло в интерпретаторе Python. Надеюсь, это будет полезно.

imanzabet 21.06.2020 04:42

Большинство из них уже ответили по существу. В качестве дополнительного примечания (на основе моего понимания и экспериментов, но не из документированного источника) утверждение

== if the objects referred to by the variables are equal

из приведенных выше ответов следует читать как

== if the objects referred to by the variables are equal and objects belonging to the same type/class

. Я пришел к такому выводу на основании следующего теста:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

Здесь содержимое списка и кортежа одинаковы, но тип / класс различаются.

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

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

Разница в Python между is и equals (==)

The is operator may seem like the same as the equality operator but they are not same.

The is checks if both the variables point to the same object whereas the == sign checks if the values for the two variables are the same.

So if the is operator returns True then the equality is definitely True, but the opposite may or may not be True.

Вот пример, демонстрирующий сходство и различие.

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.

Пожалуйста, используйте блочные кавычки только для текста, который вы цитируете из другого источника, в этот момент вы должны указать авторство (см. stackoverflow.com/help/referencing). Если это ваш собственный текст, удалите кавычки.

Martijn Pieters 24.08.2018 19:32

Другие вопросы по теме