《python基礎編程》里有講到一段高級排序:
“如果希望元素能按照特定的方式進行排序(而不是sort函數默認的方式,即根據python的默認排序規則按升序排列元素,第5章內對此進行講解),那么可以通過compare(x,y)的形式自定義比較函數。compare(x,y)函數會在x<y時返回負數,在x>y時返回正數,如果x=y則返回0(根據你的定義)。定義好該函數之后,就可以提供給sort方法作為參數了。內建函數cmp提供了比較函數的默認實現方式:
>>>cmp(42,32) 1 >>>cmp(99,100) -1 >>>cmp(10,10) 0 >>>numbers = [5,2,9,7] >>>numbers.sort(cmp) >>>numbers [2,5,7,9]
"
對於sort()方法,如果不傳入參數,默認cmp為None,即numbers.sort()=number,sort(cmp)=number.sort(cmp=None),我們可以做一個驗證:
>>> numbers = [5,2,9,7]
>>> numbers.sort()
>>> numbers
[2, 5, 7, 9]
>>> numbers = [5,2,9,7]
>>> numbers.sort(cmp)
>>> numbers
[2, 5, 7, 9]
>>> numbers = [5,2,9,7]
>>> numbers.sort(cmp=None)
>>> numbers
[2, 5, 7, 9]
>>>
如果傳入參數,numbers.sort(cmp=1),我們可以驗證一下,整型的參數可不可以:
>>> numbers = [5,2,9,7] >>> numbers.sort(cmp=1) Traceback (most recent call last): File "<pyshell#91>", line 1, in <module> numbers.sort(cmp=1) TypeError: 'int' object is not callable >>>
代碼報錯:int對象不是一個callable,可調用對象。callable(object) 方法用來檢測對象是否可被調用,即是否是一個函數,如果是則調用該函數的值,賦值給cmp。
那么我們如何自定義一個比較函數呢?
def mycmp1(x,y): #升序排列 return x-y def mycmp2(x,y): #降序排列 return y-x
其中的規律就是:兩兩比較,如果返回為正,則交換兩者的位置,即y在前x在后,否則x在前y在后。也可以這樣解釋,升序就是拿第一個數比對后面的數,降序就是拿最后一個數比對前面的數。
#升序排列 numbers = [5,2,9,7] def mycmp1(x,y): return x-y numbers.sort(cmp = mycmp1) print numbers >>> [2, 5, 7, 9] #降序排列 numbers = [5,2,9,7] def mycmp2(x,y): return y-x numbers.sort(cmp = mycmp2) print numbers >>> [9,7,5,2]
當然,也可以寫作numbers.sort(mycmp1),省略cmp。
我們還可以直接穿入匿名函數lambda:
#升序排列 numbers = [5,2,9,7] numbers.sort(cmp = lambda x,y: x-y) print numbers >>> [2,5,7,9] #降序排列 numbers = [5,2,9,7] numbers.sort(cmp = lambda x,y: y-x) print numbers >>> [9,7,5,2]
另外,python3.x中取消了cmp參數,也不支持直接往sort()里面傳函數,但可以構造排序函數傳遞給key來實現。