2015-09-13 34 views
-2

sorted()documentation(重點煤礦):排序()順序在某些條件下不穩定。這是故意的嗎?

內置的排序()函數保證是穩定的。 A排序是 穩定的,如果它保證不改變元件的相對順序 該比較相等 [...]

在下面的代碼,鑰匙816具有相同的值,即是他們會比較相等由key=lambda x: d[x]

d = {8: 0, 16: 0, 'a': 1}  

for i in range(200):  
    print(sorted(d, key=lambda x: d[x])) 

# Prints always the same 
# [8, 16, 'a'] 
# [8, 16, 'a'] 
# [8, 16, 'a'] 
# ...... 

現在讓我們嘗試一個小的修改到字典:

實施例1:

for i in range(10): 

    if i == 5: 

     del d[8] 
     del d[16] 

     d.update({16: 0}) 
     d.update({8: 0}) 

    print(sorted(d, key=lambda x: d[x])) 

# Prints: 
# [8, 16, 'a'] 
# [8, 16, 'a'] 
# [8, 16, 'a'] 
# [8, 16, 'a'] 
# [8, 16, 'a'] 
# [16, 8, 'a'] <----- it changed the order 
# [16, 8, 'a'] 
# [16, 8, 'a'] 
# [16, 8, 'a'] 
# [16, 8, 'a'] 

ID(d)保持相同。內容也保持不變。密鑰插入的順序有哪些變化。

注:
那些鍵被選擇,使得它們引起hash collisions:8

是否佔據一個位置或16確定由哪一個 到達方第一


示例2:

d = {8: 0, 16: 0, 'a': 1} 
c = {16: 0, 8: 0, 'a': 1} 

print(sorted(d, key=lambda x: d[x])) 
print(sorted(c, key=lambda x: d[x])) 

我知道dc是不同的對象的位置:

id(d) # 140067442777736 
id(c) # 140067442811016 

但我預計sorted()治療對象是d == c完全相同的方式。


實施例3: 一個不同的例子將是以下:

d = {'a': 0, 'b': 0, 'c': 0, 'd': 1} 

print(sorted(d, key=lambda x: d[x])) 

(未與for)上的多個不同的運行運行,這將每次給予不同的順序。

注:這是假設你使用Python 3.3 or higher和你PYTHONHASHSEED=random


問:
的順序並不穩定:

  • 爲獲得其修改爲了 (同一個對象例1)。
  • 2個比較相等的對象(示例2)。
  • 針對完全相同代碼(示例3)的不同運行。

上面提到的訂單不穩定是一個錯誤還是我錯過了什麼?我是否期望所有3個示例都有穩定的訂單,從而誤解了文檔?

編輯: 這不是重複的。 重複中沒有答案可以回答sorted()的此行爲是否有意或無意。 我知道爲什麼排序行爲的方式(我甚至故意造成這種行爲)。我不知道的是文檔是否缺少某些東西,以及在閱讀時是否得出了錯誤的結論。

+1

是什麼讓你覺得排序是錯誤的?密鑰的順序改變了。 'sorted()'維護你給它的相對順序。賦予它[16,8]與賦予它[8,16]不同。 –

+0

@MartijnPieters它的文檔讓我覺得在不同的運行中,它會得到相同的結果。它沒有。是的,'[16,8]!= [8,16]'。 **但是** {16,8} == {8,16}'。 –

+1

那麼?僅僅因爲字典是平等的並不意味着排序可以看到或關心。按照給定的順序給它一個鍵序列。你改變了這個順序。 –

回答