個人Python學習筆記(一):==和is

Python中對象包含的三個基本要素:id(身份標識),type(數據類型),value(值)python

  • ==是用來比較兩個對象的value(值)是否相等,
  • is是用來比較兩個對象的id(身份標識)是否相等

==示例:

x = y = [1, 2, 3]
z = [1, 2, 3]
print(x == y)   # True
print(x == z)   # True
print(x is y)   # True
print(x is z)   # False

print(id(x))    # 4416785008
print(id(y))    # 4416785008
print(id(z))    # 4416784504

  • x,y,z三個對象的值都是[1,2,3],因此在==的狀況下都是True
  • x和y的id相同,因此x is y 爲 True,而x和z的id不一樣,因此x is z 爲 False

 

is示例:

1、整數對象

對於整數對象,Python把一些頻繁使用的整數對象緩存起來,保存到一個叫small_ints的鏈表中,在Python的整個生命週期內,任何須要引用這些整數對象的地方,都再也不從新建立新的對象,而是直接引用緩存中的對象。Python把這些可能頻繁使用的整數對象規定在範圍[-5, 256]之間的小對象放在small_ints中,但凡是須要用些小整數時,就從這裏面取,再也不去臨時建立新的對象。緩存

  一、當整數對象在區間[-5,256]內時,is獲得的結果是True(a,b的id值相同)函數

  二、當整數對象不在區間[-5,256]內時,is獲得的結果是False(a,b的id值不一樣)性能

  三、看懂上面兩個例子後,咱們接着看如下代碼:spa

c = 257

def test():
    a = 257
    b = 257
    print(a is b)   # True
    print(a is c)   # False
    print(id(a))    # 140644774393856
    print(id(b))    # 140644774393856
    print(id(c))    # 140644774394072

test()

若是按照第2點得出的結論,257不在區間[-5,256]內,那麼兩個的is結果都應該爲False纔對,但是爲何a is b卻爲True呢?code

爲了弄清楚這個問題,首先咱們要先理解程序的代碼塊問題。Python程序由代碼塊構成,代碼塊做爲程序的一個最小基本單位來執行。一個模塊文件、一個函數體、一個類、交互式命令中的單行代碼都叫作一個代碼塊。在上面這段代碼中,由兩個代碼塊構成,c = 257做爲一個代碼塊,函數test做爲另一個代碼塊。Python內部爲了將性能進一步的提升,凡是在一個代碼塊中建立的整數對象,若是存在一個值與其相同的對象於該代碼塊中了,那麼就直接引用,不然建立一個新的對象出來。Python出於對性能的考慮,但凡是不可變對象,在同一個代碼塊中的對象,只有是值相同的對象,就不會重複建立,而是直接引用已經存在的對象。所以,不只是整數對象,還有字符串對象也遵循一樣的原則。因此 a is b就理所固然的返回True了,而ca不在同一個代碼塊中,所以在Python內部建立了兩個值都是257的對象。對象

 

注:以下圖所示,在PyCharm中運行以下代碼,獲得的結果都爲True,緣由就是由於在同一代碼塊中,值相同的對象就不會重複建立,而是直接引用已經存在的對象生命週期

a = 1   # a和b爲數值類型,在區間[-5,256]內
b = 1
print(a is b)   # True
print(id(a))    # 140586619260200
print(id(b))    # 140586619260200

a = 257   # a和b爲數值類型,不在區間[-5,256]內
b = 257
print(a is b)   # True
print(id(a))    # 140586619294392
print(id(b))    # 140586619294392

 

2、字符及字符串對象

當a,b爲字符串對象時,python中有intern機制,它指的就是在建立一個新的字符串對象時,若是已經有了和它的值相同的字符串對象,那麼就直接返回那個對象的引用,而不返回新建立的字符串對象。只包括字母數字下劃線的字符串,python會對它們使用intern機制。(因此當字符串只包括字母數字下劃線時,進行is操做返回True,若是包含其餘字符,進行is操做則返回False)字符串

a = "a_1"   # a和b爲字符串類型
b = "a_1"
print(a is b)   # True
print(id(a))    # 4454524688
print(id(b))    # 4454524688

a = "&"     # a和b爲字符串類型
b = "&"
print(a is b)   # True
print(id(a))    # 4305008120
print(id(b))    # 4305008120

注:當a,b爲單個字符對象時,進行is操做都返回Truetest

 

3、其餘類型對象

當a,b爲元組,list,dict和set類型時,進行is操做結果爲False

a = (1, 2, 3)   # a和b爲元組類型
b = (1, 2, 3)
print(a is b)   # False
print(id(a))    # 4366076016
print(id(b))    # 4366076416

a = [1, 2, 3]   # a和b爲list類型
b = [1, 2, 3]
print(a is b)   # False
print(id(a))    # 4366191216
print(id(b))    # 4366190712

a = {'is' : 1, 'equal' : 2}   # a和b爲dict類型
b = {'is' : 1, 'equal' : 2}
print(a is b)   # False
print(id(a))    # 4365197952
print(id(b))    # 4366187608

a = ([1, 2, 3])   # a和b爲set類型
b = ([1, 2, 3])
print(a is b)   # False
print(id(a))    # 4366190712
print(id(b))    # 4366191216
相關文章
相關標籤/搜索