我(错误?)在比较中使用'不是'并发现了这种奇怪的行为:
>>> 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的数字。
如果这是无效的语法,那为什么呢?我不应该至少得到警告吗?
答案 0 :(得分:5)
“is”不是对值相等的检查,而是检查两个变量是否指向对象的同一实例。
int
和string
对此感到困惑,因为is
和==
可能会因为语言内部的工作方式而产生相同的结果。< / p>
答案 1 :(得分:5)
对于较小的数字,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
。
答案 2 :(得分:4)
不要使用是[not] 来比较整数;使用==和!=代替。即使 在当前的CPython中由于优化而在小数字中起作用,但它不可靠且在语义上是错误的。语法本身是有效的,但警告的好处(必须在每次使用时检查并且对于int的子类可能有问题)可能不值得麻烦。
这在SO的其他地方有所涉及,但我刚才没有找到它。
答案 3 :(得分:0)
Int是python中的对象,默认情况下python缓存[-5,256]之间的小整数,所以在[-5,256]中使用 int 的地方是相同。
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
答案 4 :(得分:-1)
为了更好地理解为什么会发生这种情况,请查看 Python-2.6.5 / Objects / intobject.c:78:small_ints 数组和 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
>>>
删除的列表不会被销毁。它们被重用