1. 程式人生 > 實用技巧 >Python小白乾貨寶典:sorted()函式:列表元素排序

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() 函式不需要複製原有列表,消耗的記憶體較少,效率也較高。