昨天看《核心編程》發現了一個不爲人知的知識點,在Python中的字典比較和列表比較的策略居然不相同,下面作具體分析。算法
>>> dict1 = {} >>> dict2 = {'host':'earth','port':80} >>> cmp(dict1, dict2) -1 >>> dict1['host'] = 'earth' >>> cmp(dict1,dict2) -1
第一個比較中,dict1比dict2小,由於dict2有更多的元素(2個vs.0個)。在向dict1添加一個元素後,dict1仍然比dict2小(2個vs.1個),雖然添加的元素在dict2中也存在。編程
>>> dict1['port'] = 8080 >>> cmp(dict1, dict2) 1 >>> dict1['port'] = 80 >>> cmp(dict1, dict2) 0
在向dict1添加第二個元素後,兩個字典的長度相同,因此用鍵比較大小。這時鍵相等,則經過它們的值比較大小。鍵'host'的值相同,對於鍵'port',dict1中值比dict2中的值大(8080 vs. 80)。當把dict2中'port'的值設成和dict1中的值同樣,那麼兩個字典相等:它們有相同的大小、相同的鍵、相同的值,因此cmp()返回值是0。app
>>> dict1['port'] = 'tcp' >>> cmp(dict1, dict2) 1 >>> dic2['port'] = 'udp' >>> cmp(dict1,dict2) -1
當向兩個字典中的仍和一個添加新元素時,這個字典立刻會成爲大的那個字典,就像例子中的dict1同樣。向dict2添加鍵-值對後,由於兩個字典的長度又相等了,會繼續比較它們的鍵和值。tcp
>>> cdict = {'fruits':1} >>> ddict = {'fruits':1} >>> cmp(cdict,ddict) 0 >>> cdict['oranges'] = 0 >>> ddict['apples'] = 0 >>> cmp(cdict, ddict) 14
上面的例子代表cmp()能夠返回除-一、0、1外的其餘值。ui
字典比較的算法按照如下順序進行:
(1)比較字典長度
若是字典的長度不一樣,那麼用 cmp(dict1, dict2) 比較大小時,若是字典 dict1 比 dict2 長,cmp()返回正值,若是 dict2 比 dict1 長,則返回負值。也就是說,字典中的鍵的個數越多,這個字典就越大,即:
len(dict1) > len(dict2) ==> dict1 > dict2
(2)比較字典的鍵
若是兩個字典的長度相同,那就按字典的鍵比較;鍵比較的順序和 keys()方法返回鍵的順序相同。 (注意: 相同的鍵會映射到哈希表的同一位置,這保證了對字典鍵的檢查的一致性。) 這時,若是兩個字典的鍵不匹配時,對這兩個(不匹配的鍵)直接進行比較。當 dict1 中第一個不一樣的鍵大於 dict2 中第一個不一樣的鍵,cmp()會返回正值。
(3)比較字典的值
若是兩個字典的長度相同並且它們的鍵也徹底匹配,則用字典中每一個相同的鍵所對應的值進行比較。一旦出現不匹配的值,就對這兩個值進行直接比較。若 dict1 比 dict2 中相同的鍵所對應的值大,cmp()會返回正值。
(4)徹底匹配
到此爲止,即,每一個字典有相同的長度、相同的鍵、每一個鍵也對應相同的值,則字典徹底匹配,返回 0 值。code
>>> list1,list2 = [123,'xyz'],[456,'abc'] >>> cmp(list1, list2) -1 >>> >>> cmp(list2, list1) 1 >>> list3 = list2 + [789] >>> list3 [456,'abc',789] >>> >>> cmp(list2,list3) -1
當咱們比較list1和list2時,list1和list2逐項比較。第一個比較操做發生在兩個列表的第一個元素之間,好比說,123與456比較,由於123<456,因此list1被認爲小於list2
若是比較的值相等,那麼兩個序列的下一個值繼續比較,知道不相等的狀況出現,或者到達較短的一個序列的末尾。在這種狀況下,長的序列被認爲是較大的。這就是爲何上面list2<list3的緣由。
元組類型的比較也是用這種算法。it
列表比較的算法按照如下順序進行:
(1)對兩個列表的元組進行比較
(2)若是比較的元素是同類型的,則比較其值,返回結果。
(3)若是兩個元素不是同一種類型,則檢查他們是不是數字。udp
a.若是是數字,執行必要的數字強制類型轉換,而後比較。 b.若是有一方的元素是數字,則另外一方的元素「大」(數字是「最小的」)。 c.不然,經過類型名字的字母順序進行比較。
(4)若是有一個列表首先到達末尾,則另外一個長一點的列表「大」。
(5)若是咱們用盡了兩個列表的元素並且全部的元素都是相等的,那麼結果就是個平局,就是說返回一個0。方法
列表(元組)的比較原則:先大小後長短。
字典的比較原則:先長短,再鍵,再值。總結
《Python核心編程(第二版)》