Re: [問題] 關於list排序

看板Python作者 (偶爾想擺爛一下)時間15年前 (2009/11/20 14:44), 編輯推噓2(202)
留言4則, 3人參與, 最新討論串5/5 (看更多)
※ 引述《KSJ (阿真)》之銘言: : 也參考過回文的文章 跟參考文章 : 對於以下的解釋還是不解(雖然會使用了) : 想請板友們幫個忙: : : " : key 的使用方式比前面 cmp 的方式來的直覺,而且速度較快, : 因為排序的時候,只要需要比較的動作就會呼叫 cmp, : 而 key 只會被呼叫 n 次,n 是序列的長度,所以 key 的速度較快。 : " : : 我的想法是 : 比方有三個數 [小 ,大 ,中] : cmp感覺是 先抓 小 大 二個比 把小放在第一位 : 再抓 大 中 二個比 : 再抓 小 中 二個比 把中放在第二位 : 把大放在第三位 : 二個疑問: : 1. 對於key的比法(還是說 應該稱作 "準則") 是類似cmp這樣嗎?怎麼比的呢? 直接拿 key 與 cmp 參數來比較是不太適當的,因為兩者負責的工作(任務)不同, 且二者不是互斥的。 cmp 參數的責任是指出任兩個 element(a, b) 的大小: -1 for a < b 0 for a == b 1 for a > b 如果 list element 本身就是 comparable(有 natural order),而你想要 list 排序的順序就是依照 natural order,你可以不需要提供 cmp 參數。 如果你想要依照 natural order 以外的規則來排序,或者是 list element 本身 不是 comparable(比如 element 是一種複合的結構),那麼就需要提供 cmp 參數。 以 element 為複合的結構為例,自行提供的 cmp function 依照某種邏輯來決定 大小關係。比如說 list element 為 tuple,這些 tuple 皆是升冪排列的整數 數列,我希望將這些 tuple 依照其 maximum 來升冪排序。 A=[(2, 4, 6, 8), (1, 3, 5), (1, 2, 4)] A.sort(cmp=lambda a, b: cmp(a[-1], b[-1])) print A # [(1, 2, 4), (1, 3, 5), (2, 4, 6, 8)] 在不搭配 key 參數的情況下,cmp 參數帶進來的 function 在面對複合型態的 物件時,通常要做兩件事: 1.從兩個 object 中擷取主導排序的數據 2.決定擷取出來的數據的大小 在 list.sort 執行過程中(不論 list.sort 實際上是使用哪一種排序演算法),當 有需要比較某兩個 element 時,cmp 參數帶進來的 function 都會被執行一次。 key 參數負責的任務是從 element 擷取出主導 element 順序的關鍵數據,取出來的 關鍵數據必須是 comparable。 延續前面的例子: A=[(2, 4, 6, 8), (1, 3, 5), (1, 2, 4)] A.sort(key=lambda s: s[-1]) print A # [(1, 2, 4), (1, 3, 5), (2, 4, 6, 8)] 這種作法是先把一個 object sequence 經過一個 mapping 變成另一個 object sequence(兩個 object sequence 對應的 element 有關連),然後以後者來做 sorting。 [2 4 6 8] [1 3 5] [1 2 4] <=== A | | | | | | <== map(lambda s:s[-1], A) | | | 8 5 4 <=== B ↓ sort B 4 5 8 <=== sorted B | | | [1 2 4] [1 3 5] [2 4 6 8] <=== sorted A 所以在這種排序複合元素的情況下,通常指定 key 參數會比較有效率,因為 cmp 參數指定的 function 每次在決定元素大小前都要做一次擷取關鍵數據的 動作,而 key 參數指定的 function 是一開始拿來將每個元素的關鍵數據取出, 之後進行排序時就不再使用到。 如果 key 參數(function)擷取的數據的 natural order 不同你想要的順序, 可再搭配 cmp 參數。 : 2. 又對於最原本的sort()方法 是用最佳化的比法 還是最簡單的比法呢?? 有沒有客製 cmp or key function,list.sort 使用的排序演算法都是一樣的。 我猜 list.sort 應該是使用 quicksort 變化而來的演算法,可能在 list size 夠小時是使用其他的排序演算法,size 大時使用 quicksort。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 218.173.137.110 ※ 編輯: sbrhsieh 來自: 218.173.137.110 (11/20 15:05)

11/20 15:16, , 1F
簡單地說,cmp 決定任二 key 的產物的大小
11/20 15:16, 1F

11/20 15:17, , 2F
沒有指定key,key預設是identity function:lambda x: x.
11/20 15:17, 2F

11/21 16:33, , 3F
感動…我竟然看懂了q_q 感謝S大<(_ _)> 推一個
11/21 16:33, 3F

11/21 20:53, , 4F
推一個
11/21 20:53, 4F
文章代碼(AID): #1B1ZhIjB (Python)
討論串 (同標題文章)
文章代碼(AID): #1B1ZhIjB (Python)