Python標準型別的比較原則:字典VS列表(元組)

發表於2016-08-22

昨天看《核心程式設計》發現了一個鮮為人知的知識點,在Python中的字典比較和列表比較的策略竟然不相同,下面做具體分析。

字典比較原則

例子

第一個比較中,dict1比dict2小,因為dict2有更多的元素(2個vs.0個)。在向dict1新增一個元素後,dict1仍然比dict2小(2個vs.1個),雖然新增的元素在dict2中也存在。

在向dict1新增第二個元素後,兩個字典的長度相同,所以用鍵比較大小。這時鍵相等,則通過它們的值比較大小。鍵’host’的值相同,對於鍵’port’,dict1中值比dict2中的值大(8080 vs. 80)。當把dict2中’port’的值設成和dict1中的值一樣,那麼兩個字典相等:它們有相同的大小、相同的鍵、相同的值,所以cmp()返回值是0。

當向兩個字典中的仍和一個新增新元素時,這個字典馬上會成為大的那個字典,就像例子中的dict1一樣。向dict2新增鍵-值對後,因為兩個字典的長度又相等了,會繼續比較它們的鍵和值。

上面的例子表明cmp()可以返回除-1、0、1外的其他值。

字典比較總結

字典比較的演算法按照以下順序進行:
(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 值。

列表比較原則

例子

當我們比較list1和list2時,list1和list2逐項比較。第一個比較操作發生在兩個列表的第一個元素之間,比如說,123與456比較,因為123如果比較的值相等,那麼兩個序列的下一個值繼續比較,知道不相等的情況出現,或者到達較短的一個序列的末尾。在這種情況下,長的序列被認為是較大的。這就是為什麼上面list2元組型別的比較也是用這種演算法。

列表比較總結

列表比較的演算法按照以下順序進行:
(1)對兩個列表的元組進行比較
(2)如果比較的元素是同型別的,則比較其值,返回結果。
(3)如果兩個元素不是同一種型別,則檢查他們是否是數字。

(4)如果有一個列表首先到達末尾,則另一個長一點的列表“大”。
(5)如果我們用盡了兩個列表的元素而且所有的元素都是相等的,那麼結果就是個平局,就是說返回一個0。

總結

列表(元組)的比較原則:先大小後長短。
字典的比較原則:先長短,再鍵,再值。

參考來源

《Python核心程式設計(第二版)》

相關文章