python3中sort函數key如何對兩個參數作對比

  • python3以後不支持cmp,所用key函數並不直接比較任意兩個原始元素,而是經過key函數把那些元素轉換成一個個新的可比較對象,也就是元素的key,而後用元素的key代替元素去參與比較。若是原始元素原本就是可比較對象,好比數字、字符串,那麼不考慮性能優化能夠直接sort(key=lambda e: e)。不過這種基於key函數的設計傾向於每一個元素的大小有個絕對標準,但有時卻會出現單個元素並無一個絕對的大小的狀況,此時可使用 functools.cmp_to_key構建基於多個元素的比較函數。html

  • 以一個leetcode上的題爲例:python

    179. 最大數
    給定一組非負整數 nums,從新排列每一個數的順序(每一個數不可拆分)使之組成一個最大的整數。
    注意:輸出結果可能很是大,因此你須要返回一個字符串而不是整數。
    
    示例 1:
    輸入:nums = [10,2]
    輸出:"210"
    
    示例 2:
    輸入:nums = [3,30,34,5,9]
    輸出:"9534330"
    
    示例 3:
    輸入:nums = [1]
    輸出:"1"
    
    示例 4:
    輸入:nums = [10]
    輸出:"10"
     
    提示:
    1 <= nums.length <= 100
    0 <= nums[i] <= 109

    能夠看到在這道題中列表nums中兩個值的相對位置並不能由單一num決定,而是說 x與y拼接比y與x拼接的值大,那麼就用[x,y]的順序,不然用[y,x]的順序。此時就是所謂的:單個元素並無一個絕對的大小的狀況性能優化

  • 要解決這道題用sort也很簡單:函數

    from functools import cmp_to_key
    
    class Solution:
    
        def largestNumber(self, nums: List[int]) -> str:
            nums.sort(key=cmp_to_key(lambda x,y: int(str(y)+str(x)) - int(str(x)+str(y))))
            ans = ''.join([str(num) for num in nums])
            return str(int(ans))

    或者性能

    from functools import cmp_to_key
    
    def auxComp(x, y):
        if int(str(x)+str(y)) > int(str(y)+str(x)):
            return -1
        elif int(str(x)+str(y)) < int(str(y)+str(x)):
            return 1
        else:
            return 0
    
    class Solution:
    
        def largestNumber(self, nums: List[int]) -> str:
            nums.sort(key=cmp_to_key(auxComp))
            ans = ''.join([str(num) for num in nums])
            return str(int(ans))

    至於cmp_to_key中函數的條件能夠這樣理解:優化

    sort自己是升序,而題目要求是降序,所以須要cmp_to_key中反着寫(或者加上reverse=True),也就是解法中的:.net

    lambda x,y: int(str(y)+str(x)) - int(str(x)+str(y))

    以及設計

    def auxComp(x, y):
        if int(str(x)+str(y)) > int(str(y)+str(x)):
            return -1
        elif int(str(x)+str(y)) < int(str(y)+str(x)):
            return 1
        else:
            return 0
  • 一句話說:python3中一些接受key的函數中(例如sorted,min,max,heapq.nlargest,itertools.groupby),key僅僅支持一個參數,沒法實現兩個參數之間的對比。採用cmp_to_key 函數,能夠接受兩個參數,對兩個參數作處理,好比作和作差,轉換成一個參數,就能夠應用於key關鍵字了。code

參考:orm

怎麼理解Python的cmp_to_key函數?

python3 爲何取消了sort方法中的cmp參數?

一句話理解cmp_to_key函數

python sort函數內部實現原理

相關文章
相關標籤/搜索