Python小白乾貨寶典:sorted()函式:列表元素排序
定義:
sorted()函式對所有可迭代的物件進行排序操作。
內建函式 sorted 方法返回的是一個新的 list,而不是在原來的基礎上進行的操作。
語法:
sorted 語法:
sorted(iterable, cmp=None, key=None, reverse=False)
返回值:返回重新排序的列表。
引數說明:
- iterable -- 可迭代物件。
- cmp -- 比較的函式,這個具有兩個引數,引數的值都是從可迭代物件中取出,此函式必須遵守的規則為,大於則返回1,小於則返回-1,等於則返回0。
- key -- 主要是用來進行比較的元素,只有一個引數,具體的函式的引數就是取自於可迭代物件中,指定可迭代物件中的一個元素來進行排序。無論是 sort() 還是 sorted() 函式,傳入引數 key 比傳入引數 cmp 效率要高。
- reverse -- 排序規則,reverse = True 降序 , reverse = False 升序(預設)。
cmp()函式用於比較2個物件,如果 x < y 返回 -1, 如果 x == y 返回 0, 如果 x > y 返回 1
語法:
cmp( x, y )
引數:
- x -- 數值表示式。
- y -- 數值表示式。
reverse()函式:用於反向列表中元素。
語法:
list.reverse()
該方法沒有返回值,但是會對列表的元素進行反向排序。
sorted 的使用方法:
1、預設情況下,sorted 函式將按列表升序進行排序,並返回一個新列表物件,原列表保持不變,最簡單的排序。
>>> nums = [3,4,5,2,1] >>> sorted(nums) [1, 2, 3, 4, 5]
2、降序排序,如果要按照降序排列,只需指定引數 reverse=True 即可
>>> sorted(nums, reverse=True)
[5, 4, 3, 2, 1]
3、如果要按照某個規則排序,則需指定引數key, key 是一個函式物件,例如字串構成的列表,我想按照字串的長度來排序
>>> chars = ['Andrew', 'This', 'a', 'from', 'is', 'string', 'test'] >>> sorted(chars, key=len) ['a', 'is', 'from', 'test', 'This', 'Andrew', 'string']
len是內建函式,sorted 函式在排序的時候會用len去獲取每個字串的長度來排序。 有些人可能使用匿名函式 key=lambda x: len(x) ,
4、如果是一個複合的列表結構,例如由元組構成的列表,要按照元組中的第二個元素排序,那麼可以用 lambda 定義一個匿名函式。
>>> students = [('zhang', 'A'), ('li', 'D'), ('wang', 'C')] >>> sorted(students, key=lambda x: x[1]) [('zhang', 'A'), ('wang', 'C'), ('li', 'D')]
這裡將按照字母 A-C-D 的順序排列。
如果要排序的元素是自定義類,例如Student類按照年齡來排序,則可以寫成
>>>a = [5,7,6,3,4,1,2] >>> b = sorted(a) # 保留原列表 >>> a [5, 7, 6, 3, 4, 1, 2] >>> b [1, 2, 3, 4, 5, 6, 7] >>> L=[('b',2),('a',1),('c',3),('d',4)] >>> sorted(L, cmp=lambda x,y:cmp(x[1],y[1])) # 利用cmp函式 [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> sorted(L, key=lambda x:x[1]) # 利用key [('a', 1), ('b', 2), ('c', 3), ('d', 4)] >>> students = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] >>> sorted(students, key=lambda s: s[2]) # 按年齡排序 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)] >>> sorted(students, key=lambda s: s[2], reverse=True) # 按降序 [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] >>>
6、和資料庫的排序一樣,sorted 也可以根據多個欄位來排序,例如我有先要根據age排序,如果age相同的則根據grade排序,則可以使用元組:
>>> sorted(student_objects, key=lambda t:(t.age, t.grade)) [('dave', 'B', 10), ('lily', 'A', 12), ('jane', 'B', 12), ('john', 'A', 15)]
7、同樣的,對於自定義類,也有一種更高效的方法指定key
>>> from operator import attrgetter >>> sorted(student_objects, key=attrgetter('age')) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
如果參與排序的欄位有兩個怎麼辦?
>>> sorted(student_objects, key=attrgetter('grade', 'age')) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
8、前面碰到的排序場景都是建立在兩個元素是可以互相比較的前提下,例如數值按大小比較, 字母按順序比較。
如果遇到本身是不可比較的,需要我們自己來定義比較規則的情況如何處理呢?
>>> nums = [2, 1.5, 2.5, '2', '2.5'] >>> sorted(nums) TypeError: '<' not supported between instances of 'str' and 'int'
一個整數列表中,可能有數字,字串,在Python3中,字串與數值是不能比較的,而Python2中任何型別都可以比較,這是兩個版本中一個很大的區別:
# python2 >>> "2.5" > 2 True # python3 >>> "2.5" > 2 TypeError: '>' not supported between instances of 'str' and 'int'
9、關於 sorted 函式,當遇到需要自定義比較操作的資料,Python2和Python3之間的區別是:
Python2中的sorted 可以指定cmp關鍵字引數,可以通過 cmp=compare 來實現,
Python3中還需要匯入functools.cmp_to_key實現
sorted()函式使用範圍:
- 對字典進行排序(中根據字典的值進行排序)
- 多維list排序
- 字典中混合list排序
- List 中混合字典排序
- 對字串進行排序
sort()與sorted()的區別
1、相比於 sort(),sorted() 使用的範圍更為廣泛,兩者的函式形式分別如下:
sorted(iterable[, cmp[, key[, reverse]]])
s.sort([cmp[, key[, reverse]]])
2、sorted() 作用於任意可迭代的物件,而 sort()一般作用於列表。
>>> a = (1,2,4,2,3) >>> a.sort() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'sort' >>> sorted(a) [1, 2, 2, 3, 4]
下面的例子中針對元組使用 sort() 方法會丟擲 AttributeError,而使用 sorted() 函式則 沒有這個問題。
3、當排序物件為列表的時候兩者適合的場景不同。sorted() 函式會返回一個排序後的列表,原有列表保持不變;而 sort() 函式會直接修改原有列表,永久改變,無法返回,函式返回為 None。
>>> a=['1',1,'a',3,7,'n'] >>> sorted(a) [1, 3, 7, '1', 'a', 'n'] >>> a ['1', 1, 'a', 3, 7, 'n'] >>> print a.sort() None >>> a [1, 3, 7, '1', 'a', 'n']
如果實際應用過程中需要保留原有列表,使用 sorted() 函式較為適合,否則可以選擇sort() 函式,因為 sort() 函式不需要複製原有列表,消耗的記憶體較少,效率也較高。