1. 程式人生 > >Python中sort以及sorted函式初探

Python中sort以及sorted函式初探

sorted(...)

Help on built-in function sorted in module __builtin__:

sorted(...)

    sorted(iterable, cmp=None, key=None, reverse=False) --> new sorted list

sort(...)

Help on built-in function sort:
sort(...)
    L.sort(cmp=None, key=None, reverse=False) -- stable sort *IN PLACE*;
    cmp(x, y) -> -1, 0, 1

sorted與sort的區別

1. sorted函式是內建函式,而sort是序列的內部函式,所以它們呼叫方式不一樣,另外sorted函式多了一個系列迭代器引數

2. sorted函式不改變引數系列,但是返回排好序的序列副本;而sort作為序列的內部函式,呼叫完後會對呼叫的序列進行排序

下面的結果很好的說明了這些:

>>> list=[2,1]
>>> x=sorted(list)
>>> x
[1, 2]
>>> list
[2, 1]
>>> y=list.sort()
>>> y
>>> list
[1, 2]

sorted與sort的引數

sorted與sort除了一個是序列作為引數,一個是序列呼叫該函式,其他引數幾乎完全一致,下面逐一來介紹其用法及效果:

1. 預設用法

由於sort函式的引數reverse,key,cmp都提供了預設引數,所以我們可以直接不指定這些引數值呼叫該函式。但是它必須有一個前提,就是list中存放的型別是可比較的。否則就會彈出錯誤“Type Error: unorderable type"。

2. reverse引數

當取值為True時候就是倒序排,預設為False正序從小到大排

>>> list.sort(reverse=False)
>>> list
[1, 2]
>>> list.sort(reverse=True)
>>> list
[2, 1]

3. key引數

key表示用來做比較的值,這個主要對自定義的資料型別有用。下面用一個例子來詮釋:
# Definition for an interval.
class Interval:
	def __init__(self, s=0, e=0):
		self.start = s
		self.end = e

# Initialize the Interval list
list = []
for i in range(10,7,-1):
	for j in range(11,i,-1):
		list.append(Interval(i,j))
這裡我們定義了Interval為[s,e]的資料結構並且初始化了。對於這個問題,顯然我們用預設的引數來呼叫會出錯,因為我們沒有提供可比較的函式來比較型別Interval。對於這樣的情況,我們就可以指定比較的key來解決。
#Sort the Interval list
list2 = sorted(list,key=lambda x:x.start)

#Output the Interval list
for x in list:
	print("[%d,%d]"%(x.start,x.end))
for x in list2:
	print("[%d,%d]"%(x.start,x.end))
這裡我們基於Interval.start作為key進行排序了。 可是接著問題來了,如果我不僅比較Interval.start,當Interval.start相等時候,還想比較Interval.end,該怎麼辦?
#Sort the Interval list based on Interval.start and Interval.end
list2 = sorted(list,key=lambda x:(x.start,x.end))
我們用元祖(Interval.start,Interval.end)作為key來比較,而元祖有預設的cmp函式。這就達到了目標。

4. cmp引數

我們可以通過自定義函式或則使用簡潔的lambda來作為引數傳給cmp
#Sort the Interval list based on Interval.start and Interval.end
def cmpInterval(a, b):
	if a.start != b.start:
		return cmp(a.start,b.start)
	return cmp(a.end,b.end)
list1 = sorted(list,cmp = cmpInterval)
list2 = sorted(list,cmp = lambda x,y:cmp(x.start,y.start))
不過比較遺憾的是發現在python 3.x中傳入cmp函式會出現一個錯誤:TypeError: 'cmp' is an invalid keyword argument for this function 這時候我們就需要使用key來繞過這個問題。另外一個建議就是我們儘量使用key而不是cmp來排序以提高執行速度。