Несколько дней назад, просматривая подпункт «learnpython» на Reddit, я увидел, что Redditor снова задает этот вопрос. Хотя ответов и пояснений на этот вопрос в Интернете слишком много, многие новички до сих пор не знают об этом и совершают ошибки. Вот вопрос

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

И ==, и is являются операторами в Python (Ссылка на страницу оператора в Python). Для новичков они могут интерпретировать a == b как a равно b и a is b, ну, ну, a is b. Вероятно, поэтому новички путают == и есть в Python.

Я хочу сначала показать несколько примеров использования «==» и «есть» перед подробным обсуждением.

>>> a = 5
>>> b = 5
>>> a == b
True
>>> a is b
True

Все просто, правда? a == b и a is b оба возвращают True. Затем переходите к следующему примеру.

>>> a = 1000
>>> b = 1000
>>> a == b
True
>>> a is b
False

Какого черта?!? Единственное отличие от первого примера ко второму - это значения a и b от 5 до 1000. Но результаты уже различаются между «==» и «is». Перейти к следующему.

>>> a = []
>>> b = []
>>> a == b
True
>>> a is b
False

Вот последний пример, если вы все еще не взорвали.

>>> a = 1000
>>> b = 1000
>>> a == b
True
>>> a is b
False
>>> a = b 
>>> a == b
True
>>> a is b
True

Официальная операция для «==» - это равенство, а операция для «есть» - это идентичность. Вы используете «==» для сравнения значений двух объектов. «A == b» следует интерпретировать как «значение a равно значению b». Во всех приведенных выше примерах значение a всегда равно значению b (даже для примера с пустым списком). Следовательно, «a == b» всегда верно.

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

>>> id(a)
2047616

Оператор «есть» предназначен для сравнения идентичности двух объектов. «A is b» означает «идентичность a совпадает с идентичностью b».

Как только вы узнаете истинное значение «==» и «есть», мы можем начать углубляться в приведенные выше примеры.

Во-первых, это разные результаты в первом и втором примерах. Причина отображения разных результатов заключается в том, что Python хранит список массивов целых чисел от -5 до 256 с фиксированной идентичностью для каждого целого числа. Когда вы назначаете переменную целого числа в пределах этого диапазона, Python присваивает идентификатор этой переменной как единицу для целого числа внутри списка массивов. В результате для первого примера, поскольку идентификаторы a и b получаются из списка массивов, их идентификаторы, конечно же, совпадают, и поэтому a is b истинно.

>>> a = 5
>>> id(a)
1450375152
>>> b = 5
>>> id(b)
1450375152

Но как только значение этой переменной выходит за пределы этого диапазона, поскольку внутри Python нет объекта с этим значением, Python создаст новый идентификатор для этой переменной и присвоит значение этой переменной. Как было сказано ранее, идентичность уникальна для каждого творения, поэтому даже значения двух переменных одинаковы, их идентичности никогда не равны. Вот почему a is b во втором примере - Ложь.

>>> a = 1000
>>> id(a)
12728608
>>> b = 1000
>>> id(b)
13620208

(Дополнительно: если вы откроете две консоли, вы получите ту же идентификацию, если значение все еще находится в пределах диапазона. Но, конечно, это не тот случай, если значение выходит за пределы диапазона.)

Как только вы поймете разницу между первым и вторым примерами, легко понять результат для третьего примера. Поскольку Python не хранит объект «пустой список», Python создает один новый объект и присваивает значение «пустой список». Результат будет одинаковым, независимо от того, пусты ли два списка или содержат одинаковые элементы.

>>> a = [1,10,100,1000]
>>> b = [1,10,100,1000]
>>> a == b 
True
>>> a is b
False
>>> id(a)
12578024
>>> id(b)
12578056

Наконец, мы переходим к последнему примеру. Единственная разница между вторым и последним примером состоит в том, что есть еще одна строка кода a = b. Однако эта строка кода меняет предназначение переменной a. Приведенный ниже результат объясняет, почему.

>>> a = 1000
>>> b = 2000
>>> id(a)
2047616
>>> id(b)
5034992
>>> a = b
>>> id(a)
5034992
>>> id(b)
5034992
>>> a
2000
>>> b
2000

Как видите, после a = b идентификатор a меняется на идентификатор b. a = b назначает личность b a. Таким образом, оба a и b имеют одинаковую идентичность, и, таким образом, значение a теперь совпадает со значением b, равным 2000.

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

>>> a = [1,2,3]
>>> id(a)
5237992
>>> b = a
>>> id(b)
5237992
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3, 4]

Из приведенного выше примера, поскольку и a, и b имеют одинаковые идентификаторы, их значения должны быть одинаковыми. Таким образом, после добавления нового элемента в a значение b также будет затронуто. Чтобы предотвратить эту ситуацию, если вы хотите скопировать значение из одного объекта в другой, не ссылаясь на один и тот же идентификатор, метод один для всех - использовать deepcopy в модуле copy (Ссылка на документ Python). Список можно также выполнить по b = a[:].

>>> import copy
>>> a = [1,2,3]
>>> b= copy.deepcopy(a)
>>> id(a)
39785256
>>> id(b)
5237992

Использование [:] для копирования элементов в новую переменную

>>> a = [1,2,3]
>>> id(a)
39785256
>>> b = a[:]
>>> id(b)
23850216
>>> a.append(4)
>>> a
[1, 2, 3, 4]
>>> b
[1, 2, 3]

Я надеюсь, что теперь вы понимаете разницу между ними и больше не будете новичком, чтобы задать этот вопрос.