sorted復雜排序--cmp_to_key


Python3中移除了cmp內建函數,sorted函數也沒有了cmp這個關鍵字參數,但可以通過functools模塊中的cmp_to_key來對自定義的cmp函數進行包裝,然后就能賦值給sorted函數的關鍵字參數key,來間接實現Python2中cmp函數用於排序的效果。

cmp_to_key是在python3中使用的,其實就是python2中的cmp函數。

python3不支持比較函數,在一些接受key的函數中(例如sorted,min,max,heapq.nlargest,itertools.groupby),key僅僅支持一個參數,就無法實現兩個參數之間的對比,采用cmp_to_key 函數,可以接受兩個參數,將兩個參數做處理,比如做和做差,轉換成一個參數,就可以應用於key關鍵字之后。

cmp_to_key 返回值小於0,則交換值。如果返回值大於等於0,則不執行任何操作。
注意點:
x = [("a", 1), ("b", 3), ("c", 2)]
在cmp_to_key中,第一個入參是 ("b", 3) ,第二個入參是 ("a", 1)

"""python2 cmp關鍵字參數"""
# 字典按key降序排序,再按val升序排序
a = {"a": 5, "c": 3, "e": 2, "d": 2}


def cmp_func(val1, val2):
    if val1[0] < val2[0]:
        return 1
    elif val1[0] > val2[0]:
        return -1
    else:
        if val1[1] > val2[1]:
            return 1
        else:
            return -1


sd = sorted(a.items(), cmp=cmp_func)
print(sd)  # [('e', 2), ('d', 2), ('c', 3), ('a', 5)]


"""python3 cmp_to_key"""
from functools import cmp_to_key

# 字典按key降序排序,再按val升序排序
a = {"a": 5, "c": 3, "e": 2, "d": 2}


def cmp_func(val1, val2):
    if val1[0] < val2[0]:
        return 1
    elif val1[0] > val2[0]:
        return -1
    else:
        if val1[1] > val2[1]:
            return 1
        else:
            return -1


# python3的sorted函數,沒有cmp參數,只能通過cmp_to_key傳給key,實現python2中sorted函數的cmp參數的功能
sd = sorted(a.items(), key=cmp_to_key(cmp_func))
print(sd)  # [('e', 2), ('d', 2), ('c', 3), ('a', 5)]


# 我們利用類的 __lt__ 也能實現cmp_to_key
class Info:
    def __init__(self, items):
        self.val = items

    def __lt__(self, other):
        # key 降序
        if self.val[0] < other.val[0]:
            return False
        elif self.val[0] > other.val[0]:
            return True

        # val 升序
        else:
            if self.val[1] > other.val[1]:
                return False
            else:
                return True


b = sorted(a.items(), key=lambda kv: Info(kv))
print(b)  # [('e', 2), ('d', 2), ('c', 3), ('a', 5)]

 


免責聲明!

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



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