Странное поведение Python из-за неуместного использования сравнения «не»? - PullRequest
2 голосов
/ 12 июля 2010

Я (неправильно?) Использовал 'нет' в сравнении и обнаружил это любопытное поведение:

>>> a = 256
>>> b = int('256')
>>> c = 300
>>> d = int('300')
>>>
>>> a is not b
False
>>> c is not d
True

Очевидно, я должен был использовать:

>>> a != b
False
>>> c != d
False

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

Если это неверный синтаксис, то почему?И не должен ли я хотя бы получить предупреждение?

Ответы [ 5 ]

5 голосов
/ 12 июля 2010

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

int s и string s путают это какis и == могут давать один и тот же результат из-за того, как работают внутренние компоненты языка.

5 голосов
/ 12 июля 2010

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

Смотрите это:

>>> a=256
>>> b=int('256')
>>> c=300       
>>> d=int('300')

>>> id(a)
158013588
>>> id(b)
158013588
>>> id(c)
158151472
>>> id(d)
158151436

именно поэтому a является b, но c не d.

4 голосов
/ 12 июля 2010

Не используйте для [не] для сравнения целых чисел;используйте == и! = вместо.Хотя это работает в текущем CPython для небольших чисел из-за оптимизации, это ненадежно и семантически неправильно.Сам синтаксис действителен, но преимущества предупреждения (которое должно проверяться при каждом использовании равно и может быть проблематичным для подклассов int), по-видимому, не стоят проблем.

Это рассматривается в другом месте на SO, но я не нашел его только сейчас.

0 голосов
/ 29 мая 2015

Int - это объект в python , и python по умолчанию кэширует небольшое целое число между [-5,256], поэтому при использовании int в [-5,256] они идентичны.

a = 256
b = 256

a is b # True

Если вы объявите два целых числа не в [-5,256], python создаст два не совпадающих объекта (хотя они имеют одинаковое значение).

a = 257
b = 257

a is b # False

В вашем случае использование != вместо сравнения является правильным способом.

a = 257
b = 257

a != b # False
0 голосов
/ 12 июля 2010

Чтобы лучше понять, почему это происходит, взгляните на Python-2.6.5 / Objects / intobject.c: 78: small_ints array и Python-2.6.5 / Objects / intobject.c : 1292: функция _PyInt_Init в источниках Python.

То же самое происходит со списками:


>>> a = [12]
>>> id_a = id(a)
>>> del(a)
>>> id([1,2,34]) == id_a
True
>>> 

Удаленные списки не уничтожаются. Они используются повторно

...