Python3自定义排序方法

假设有这样一个问题:
[[15, 1], [14, 2], [13, 3], [12, 4]]按照第二元素进行非递增排序。
由于数据是个列表,所以可以使用list自带的sort()函数,也可以使用通用的sorted()函数。
但是最关键的问题在于,如何指定采用第二个元素进行排序。
有如下三种方案:

# 方案1
l = [[15, 2], [14, 4], [13, 6], [12, 8]]
l.sort(key=lambda elem:elem[1], reverse=True)

# 方案2
from operator import itemgetter
l = [[15, 2], [14, 4], [13, 6], [12, 8]]
l = sorted(l, key=itemgetter(1), reverse=True)

# 方案3
l = [[15, 2], [14, 4], [13, 6], [12, 8]]
l = sorted(l, key=lambda elem:elem[1], reverse=True)

这三种方案都是采用了元素本身携带的属性进行排列,都可以完成任务,但有些情况需要实现自定义排序方案,该排序元素并非元素本身的属性,例如要按列表内元素的和进行排序,即期望的结果为:
[[12, 8], [13, 6], [14, 4], [15, 2]]
因为12+8 > 13+6 > 14+4 > 15+2。
两种方案:

# 方案1
import functools
def cmp_func(a, b):
    if a > b:
        return -1
    elif a < b:
        return 1
    else:
        return 0

l = [[15, 2], [14, 4], [13, 6], [12, 8]]
l = sorted(l, key=functools.cmp_to_key(cmp_func), reverse=True)

# 方案2
class LargerNumKey(list):
    def __lt__(x, y):
        return x[0]+x[1] < y[0]+y[1]

l = [[15, 2], [14, 4], [13, 6], [12, 8]]
l = sorted(l, key=LargerNumKey, reverse=True)

在方案1中,采用了一种比较熟知的方案,自定义cmp函数,注意的是如果a>b返回值应该是-1a<b返回值应该是1。熟悉cpp的就应该发现,和cppcmp函数是正好反着的,但又恰好和greaterless这样的函数对象又是一致的。

在方案2中,就类似cpp中采用operator重载比较符号的方法了。要注意的点在于,这个类要集成自,输入对象,也就是要比较的数据对象类型;其次,在__lt__中重定义了小于号。
另:

  1. 当自定义类中两个方法都定义了时,“<”、“>”分别调用__lt____gt__方法;
  2. 当自定义类中定义了__lt__方法,未定义__gt__方法时,进行”>”比较也是调用__lt__方法,只是对调用值求反;
  3. 当自定义类中定义了__gt__方法,未定义__lt__方法时,进行”<”比较也是调用__gt__方法,只是对调用值求反。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值