自定义排序规则:functools.cmp_to_key(callable)

1.functools.cmp_to_key()是什么

简单来说,它的功能就是定义排序时的规则,使数组按照自己定义的规则进行排序。

2.functools.cmp_to_key()怎么用

举例来说:一个数组[1,0,-10,200,3,7],正常按照从小到大进行排序,结果为:[-10, 0, 1, 3, 7, 200]。

3.functools.cmp_to_key(callable)框架

下面代码的1表示相反,-1表示保持。  

(1).单个比较

这个框架是单层的if-elif-else,适用于单个比较大小

import functools

def mycmp(x,y):   # 只需要把func(x)和func(y)改成你想要的规则
    if func(x) > func(c):
        return 1
    elif func(x) < func(y):
        return -1
    else:
        return 0

if __name__ == '__main__':
    arr = [a,b,c,d,e,f,.....] # 字母代表你需要排序的数字
    arr.sort(key=functools.cmp_to_key(mycmp))
    print(arr)

(2).有优先级的比较 

两个或者三个有优先级的比较的话需要两层if-elif-else。 

以三个有优先级的比较为例:优先级为(1,2,0),a[1]和a[2]降序,a[0]升序。

import functools
def cmp(n1,n2):                         
    if n1[1]!=n2[1]:                    # 1不一样,降序
        return -1 if n1[1]>n2[1] else 1
    elif n1[2] != n2[2]:                # 2不一样,降序
        return -1 if n1[2]>n2[2] else 1
    else:                               # 0不一样,升序
        return 1 if n1[0]>n2[0] else -1

先比较第一个:a[1],再比较第二个a[2],最后比较第0个:a[0]

4.举例

如果我们想按照数组中元素的绝对值进行排序,可以把上面框架中的func(x)和func(y)改成abs(x)和abs(y)即可。那我们就可以采用如下的代码:

import functools

def mycmp(x,y): 
    if abs(x) > abs(y): # 1表示相反,-1表示保持
        return 1
    elif abs(x) < abs(y):
        return -1
    else:
        return 0

if __name__ == '__main__':
    arr = [1,0,-10,200,3,7]
    arr.sort(key=functools.cmp_to_key(mycmp))
    print(arr)
# 打印结果:[0, 1, 3, 7, -10, 200]

上述代码中我们定义排序规则mycmp:对于两个数字x和y,我们定义绝对值大的为“大”,绝对值小的为“小”。之后我们通过key参数告诉数组的内置函数sort,让它明白如何对两个数进行比较,清楚哪个是“大”的,哪个是“小”的。比如对于0和-10,|0|<|-10|,因此对于规则mycmp,0<-10。(注:定义排序规则只是为了明白如何得到两个数之间较“大”的一个,与数组是从“小”到“大”还是从“大”到“小”排序,是没有关系的,这个是由排序的另一个参数:reverse = True/False来确定,我们定义排序规则,只是需要弄清楚谁是“大”的)


再举一个栗子,我们想按照数组中元素的相反数进行排序(从小到大),只需要把上面框架中的func(x)和func(y)改成-x和-y即可。

import functools

def mycmp(x,y):
    if -x > -y:
        return 1  # 相反
    elif -x < -y:  
        return -1 # 保持
    else:
        return 0

if __name__ == '__main__':

    arr = [1,0,-10,200,3,7]
    arr.sort(key=functools.cmp_to_key(mycmp))
    print(arr)
# 打印结果:[200, 7, 3, 1, 0, -10]

 特殊情况:以下面第三行代码进行说明:如果y-x<0,则等价于-1的情况,不需要交换,即前面比后面大,降序;同理,y-x>0等价于1,交换,即前面大于后面,降序。第四行代码也是这样去分析。

from functools import cmp_to_key

nums = [3, 30, 34, 5, 9]
new_nums = sorted(nums, key=cmp_to_key(lambda x, y: y - x)) # 后-前 降序
new_nums2 = sorted(nums, key=cmp_to_key(lambda x, y: x - y)) # 前-后 升序 
print(new_nums)
print(new_nums2)
#结果:
#[34, 30, 9, 5, 3]
#[3, 5, 9, 30, 34]

5.蓝桥杯省赛实战

 

这道题是一个有优先级的三比较的题目 ,先总分,再语文,最后学号,需要两层if-elif-else,第一层是判断总分是同(if)/语文是否相同(elif)/(else),第二层分别比较总分/语文/学号

import functools
def cmp(n1,n2):                         
    if n1[1]!=n2[1]:                    # 总分不一样的,高分在前
        return -1 if n1[1]>n2[1] else 1
    elif n1[2] != n2[2]:                # 总分一样,语文不一样的,语文高在前
        return -1 if n1[2]>n2[2] else 1
    else:                               # 成绩,语文都一样的,学号小的在前
        return 1 if n1[0]>n2[0] else -1
n = int(input())
scores = []
for i in range(n):
    score = list(map(int,input().split()))
    scores.append([i+1,sum(score)]+score)
# scores.sort(key=functools.cmp_to_key(cmp))  #  用sort
scores = sorted(scores,key=functools.cmp_to_key(cmp)) # 用sorted
for i in range(5):
    print(scores[i][0],scores[i][1])

  • 11
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
The `functools.cmp_to_key` function is a utility function in Python's `functools` module that helps convert a comparison function to a key function. In Python, sorting a list of objects requires a way to compare the objects. This is done by providing a comparison function that takes two objects as input and returns `-1`, `0`, or `1` depending on whether the first object is less than, equal to, or greater than the second object. However, some sorting functions in Python (such as the `sorted` function) require a key function instead of a comparison function. A key function takes a single object as input and returns a value that can be used for sorting. The `cmp_to_key` function helps convert a comparison function to a key function by returning a new function that takes a single object as input and returns a tuple `(comparison_result, object)` where `comparison_result` is the result of calling the original comparison function with the input object and another object, and `object` is the input object itself. This tuple can then be used for sorting. Here's an example of how to use `cmp_to_key`: ``` from functools import cmp_to_key def compare_length(str1, str2): if len(str1) < len(str2): return -1 elif len(str1) > len(str2): return 1 else: return 0 strings = ['cat', 'dog', 'elephant', 'a', 'zebra'] sorted_strings = sorted(strings, key=cmp_to_key(compare_length)) print(sorted_strings) # Output: ['a', 'cat', 'dog', 'zebra', 'elephant'] ``` In this example, we define a comparison function `compare_length` that compares the lengths of two strings. We then use `cmp_to_key` to convert this comparison function to a key function, and pass it to the `sorted` function to sort a list of strings by length. The resulting sorted list is `['a', 'cat', 'dog', 'zebra', 'elephant']`.

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小叶pyか

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值