python1-python3中sort函數key如何對兩個參數做對比


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

  • 以一個leetcode上的題為例:

    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),也就是解法中的:

    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關鍵字了。

參考:

怎么理解Python的cmp_to_key函數?

python3 為什么取消了sort方法中的cmp參數?

一句話理解cmp_to_key函數

python sort函數內部實現原理


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM