Python3使用sorted函數對列表元素進行多字段排序

Python3 的 sorted 函數相信你們都會,不外乎像下面這種:python

>>> pairs = [('11', 'one'),('3', 'three'), ('2', 'two'),('2', 'zzz'), ('4', 'four')]
>>> sorted(pairs)
[('11', 'one'), ('2', 'two'), ('2', 'zzz'), ('3', 'three'), ('4', 'four')]

但這或許不是你指望的排序結果。你或許但願列表元素 ('11', 'one') 最好排在最後邊,可是因爲 sorted 對字符串默認是按照 ASCII 排序的,而字符串 「11」 的第一個字符在 ASCII 表中處於 「2」、"3" 和 "4"的前邊,固然,若是你把這些數字轉換成整型而非字符型的話,排序天然不會出現這種問題。sql

而後你會想到 sorted 函數有一個 key 關鍵字參數,因而你想,那我讓字符串長度更長的排在後邊總能夠了吧,因此你按照這種想法添加以下限制:數據庫

>>> sorted(pairs, key=lambda x: len(x[0]))
[('3', 'three'), ('2', 'two'), ('2', 'zzz'), ('4', 'four'), ('11', 'one')]

可是如今的問題是:列表元素 ('11', 'one') 雖然確乎的確已經排在最後邊了,但 ('3', 'three') 居然排在了 ('2', 'two') 的前邊,這確定是你不想看到的。你因而慢慢冥想,要是能把這些元素存到數據庫就行了,這樣我就能夠用SQL語句了:函數

SELECT field1, field2 FROM test_table ORDER BY LENGTH(field1), field1 ASC, field2 ASC;

但這種排序問題天然用不着動用數據庫,殺雞焉用牛刀,實際上,只要用好殺雞的這把刀就行了:code

>>> sorted(pairs, key=lambda x: (len(x[0]), x[0]))
[('2', 'two'), ('2', 'zzz'), ('3', 'three'), ('4', 'four'), ('11', 'one')]
>>> sorted(pairs, key=lambda x: (len(x[0]), x[0], x[1]))
[('2', 'two'), ('2', 'zzz'), ('3', 'three'), ('4', 'four'), ('11', 'one')]

雖然 sorted 函數的參數說明有說,key 主要是用來選取進行比較的元素,只有一個參數,具體的函數的參數就是取自於可迭代對象中。可是你能夠將多個排序規則用元組的方式組合起來做爲 key 中函數的返回值,以此來達到對迭代元素進行多字段排序的效果。對象

固然,對於列表的 sort 函數也有相似的效果,只不過 sorted 是返回排好序的新列表, sort 是對原列表進行修改,使得原列表的順序發生變化。排序