Strange Python behavior from inappropriate usage of 'is not' comparison?

好久不见. 提交于 2019-12-02 02:01:13

"is" is not a check of equality of value, but a check that two variables point to the same instance of an object.

ints and strings are confusing for this as is and == can happen to give the same result due to how the internals of the language work.

For small numbers, Python is reusing the object instances, but for larger numbers, it creates new instances for them.

See this:

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

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

which is exactly why a is b, but c isn't d.

Don't use is [not] to compare integers; use == and != instead. Even though is works in current CPython for small numbers due to an optimization, it's unreliable and semantically wrong. The syntax itself is valid, but the benefits of a warning (which would have to be checked on every use of is and could be problematic with subclasses of int) are presumably not worth the trouble.

This is covered elsewhere on SO, but I didn't find it just now.

Int is an object in python, and python caches small integer between [-5,256] by default, so where you use int in [-5,256], they are identical.

a = 256
b = 256

a is b # True

If you declare two integers not in [-5,256], python will create two objects which are not the same(though they have the same value).

a = 257
b = 257

a is b # False

In your case, using != instead to compare the value is the right way.

a = 257
b = 257

a != b # False

For more understanding why this occurs take a look to Python-2.6.5/Objects/intobject.c:78:small_ints array and Python-2.6.5/Objects/intobject.c:1292:_PyInt_Init function in python sources.

Also similar thing occurs with lists:


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

Removed lists are not destroyed. They are reused

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!