Python 整數比較(is, )

2021-09-21 06:47:58 字數 2619 閱讀 6604

在 python 中一切都是物件,整數也是物件,在比較兩個整數時有兩個運算子==is,它們的區別是:

知道了is==的區別之後,我們可以來看看下面的**,了解python中整數比較有哪些坑:

def

main()

: x = y =-1

while

true

: x +=

1 y +=

1if x is y:

print

('%d is %d'

%(x, y)

)else

:print

('attention! %d is not %d'

%(x, y)

)break

x = y =

0while

true

: x -=

1 y -=

1if x is y:

print

('%d is %d'

%(x, y)

)else

:print

('attention! %d is not %d'

%(x, y)

)break

if __name__ ==

'__main__'

: main(

)

上面**的部分執行結果如下圖所示,出現這個結果的原因是python出於對效能的考慮所做的一項優化。對於整數物件,python把一些頻繁使用的整數物件快取起來,儲存到乙個叫small_ints的鍊錶中,在python的整個生命週期內,任何需要引用這些整數物件的地方,都不再重新建立新的物件,而是直接引用快取中的物件。python把頻繁使用的整數物件的值定在[-5, 256]這個區間,如果需要這個範圍的整數,就直接從small_ints中獲取引用而不是臨時建立新的物件。因為大於256或小於-5的整數不在該範圍之內,所以就算兩個整數的值是一樣,但它們是不同的物件。

當然僅僅如此這個坑就不值一提了,如果你理解了上面的規則,我們就再看看下面的**。

import dis

a =257

defmain()

: b =

257# 第6行

c =257# 第7行

print

(b is c)

# true

print

(a is b)

# false

print

(a is c)

# false

if __name__ ==

"__main__"

: main(

)

程式的執行結果已經用注釋寫在**上了。夠坑吧!看上去abc的值都是一樣的,但是is運算的結果卻不一樣。為什麼會出現這樣的結果,首先我們來說說python程式中的**塊。所謂**塊是程式的乙個最小的基本執行單位,乙個模組檔案、乙個函式體、乙個類、互動式命令中的單行**都叫做乙個**塊。上面的**由兩個**塊構成,a = 257是乙個**塊,main函式是另外乙個**塊。python內部為了進一步提高效能,凡是在乙個**塊中建立的整數物件,如果值不在small_ints快取範圍之內,但在同乙個**塊中已經存在乙個值與其相同的整數物件了,那麼就直接引用該物件,否則建立乙個新的物件出來,這條規則對不在small_ints範圍的負數並不適用,對負數值浮點數也不適用,但對非負浮點數和字串都是適用的,這一點讀者可以自行證明。所以b is c返回了true,而ab不在同乙個**塊中,雖然值都是257,但卻是兩個不同的物件,is運算的結果自然是false了。

為了驗證剛剛的結論,我們可以借用dis模組(聽名字就知道是進行反彙編的模組)從位元組碼的角度來看看這段**。如果不理解什麼是位元組碼,可以先看看《談談 python 程式的執行原理》這篇文章。可以先用import dis匯入dis模組並按照如下所示的方式修改**。

if __name__ ==

"__main__"

: main(

) dis.dis(main)

**的執行結果如下圖所示。可以看出**第6行和第7行,也就是main函式中的257是從同乙個位置載入的,因此是同乙個物件;而**第9行的a明顯是從不同的地方載入的,因此引用的是不同的物件。

如果還想對這個問題進行進一步深挖,推薦大家閱讀《python整數物件實現原理》這篇文章。

Python解惑 整數比較

python 中常用的資料型別bool 布林 型別的例項物件 值 就兩個,真和假,分別用true和false表示。在if 條件判斷和while 語句中經常用到,不過在python2.x 中,true 和false 卻有著奇怪的用法,就是真假可以相互被替換,先看下面 true true false f...

Python 整數物件is比較

python 整數用is比較 is 比較的是兩個物件的id值 記憶體中的位址 5,256 之間常用整數對比 在比較整數時,要知道python對於常用整數的儲存,5,256 之間的整數是存放在快取中的鍊錶中,需要使用時不再建立新的物件,而是直接引用物件 通過以下 可以看到區別 a 10 b 10 a ...

python類整數 整數類python

sinteger類基於位列表。它是位長度為len的有符號整數。len是在測試用例中定義的,因此您可以簡單地使用它而不必重新定義它。雖然位字串 bit str 可能必須短於len,但應進行符號擴充套件。如果輸入位字串是空字串,則新的sinteger物件應該是乙個全零的列表。請注意,列表中儲存的所有位物...