1. 程式人生 > >關於python中的is和==的區別

關於python中的is和==的區別

效率 什麽 比較 == 操作 切片 har none 人的

在 Python 中會用到對象之間比較,可以用 ==,也可以用 is 。但是它們的區別是什麽呢?

  • is 比較的是兩個實例對象是不是完全相同,它們是不是同一個對象,占用的內存地址是否相同。萊布尼茨說過:“世界上沒有兩片完全相同的葉子”,這個is正是這樣的比較,比較是不是同一片葉子(即比較的id是否相同,這id類似於人的身份證標識)。

  • == 比較的是兩個對象的內容是否相等,即內存地址可以不一樣,內容一樣就可以了。這裏比較的並非是同一片葉子,可能葉子的種類或者脈絡相同就可以了。默認會調用對象的 __eq__()方法。

可以通過如下例子來區分比較下:

>>> a = ["I", "love", "Python"]
>>> b = a
# a的引用復制給b,在內存中其實是指向了用一個對象
>>> b is a
True
>>> id(a)
46381384
>>> id(b)
46381384
# 當然,內容也肯定是相等的
>>> b == a
True

可以發現b和a的內存地址是相同的,它們指向同一塊內存,因而 is 和 == 的結果都為True。這是因為直接賦值都是賦值的引用,是引用,是引用,重要的事情說三遍。但如果不是通過引用賦值,而是通過切片賦值呢?

# b通過切片操作重新分配了對象,但是值和a相同
>>> b = a[:]
>>> b is a
False
>>> id(a)
48740680
>>> id(b)
48740680
>>> b == a # 但他們的值還是相等的
True

新建對象之後,b 和 a 指向了不同的內存,所以 b is a 的結果為False,而 b==a的結果為True。在這裏,小編提一個問題,b[0] is a[0] 的結果呢?

答案是True。因為切片拷貝是淺拷貝,列表中的元素並未重新創建。不理解的同學請翻看之前的文章 Python中的淺拷貝與深拷貝。

通常,我們關註的是值,而不是內存地址,因此 Python 代碼中 == 出現的頻率比 is 高。但是什麽時候用 is 呢?

is 與 == 相比有一個比較大的優勢,就是計算速度快,因為它不能重載,不用進行特殊的函數調用,少了函數調用的開銷而直接比較兩個整數 id。而 a == b 則是等同於a.__eq__(b)。繼承自 object 的 __eq__ 方法比較兩個對象的id,結果與 is 一樣。但是多數Python的對象會覆蓋object的 __eq__方法,而定義內容的相關比較,所以比較的是對象屬性的值。

在變量和單例值之間比較時,應該使用 is。目前,最常使用 is 的地方是判斷對象是不是 None。下面是推薦的寫法:

a is None

判斷不是None的推薦寫法是:

a is not None

Python會對比較小的整數對象進行緩存,下次用的時候直接從緩存中獲取,所以is 和 == 的結果可能相同:

>>> a = 1
>>> b = 1
>>> a is b
True
>>> a == b
True

而看一下另外一段代碼:

>>> a = 257
>>> b = 257
>>> a is b
False

這是什麽原因呢?

註意,Python僅僅對比較小的整數對象進行緩存(範圍為範圍[-5, 256])緩存起來,而並非是所有整數對象。需要註意的是,這僅僅是在命令行中執行,而在Pycharm或者保存為文件執行,結果是不一樣的,這是因為解釋器做了一部分優化。

總結

1、is 比較兩個對象的 id 值是否相等,是否指向同一個內存地址;
2、== 比較的是兩個對象的內容是否相等,值是否相等;
3、小整數對象[-5,256]在全局解釋器範圍內被放入緩存供重復使用;
4、is 運算符比 == 效率高,在變量和None進行比較時,應該使用 is。

(本文來源於博主kiko0o0的博客)

關於python中的is和==的區別