首页 > 其他分享 >sorted函数中的key

sorted函数中的key

时间:2022-10-06 18:11:32浏览次数:50  
标签:__ 函数 age lt ls key sorted self

sorted函数有三个参数:iterable、key、reverse。

其中,iterable为一个可迭代的对象,reverse表示是否对排序结果进行反转,而key稍微复杂一点,主要是用来对需要比较的元素进行处理,可以是一个函数,也可以是一个类,也可以是其他的处理方法。

key的工作原理

key的大概工作流程就是首先对序列中所有的元素逐一调用方法、函数或者类进行处理,如果是方法,一般是返回一个固定的值这个值一般是内置的类型。如果是类,则是直接调用构造函数,生成一个对象,所以作为key的类必须有一个构造函数,这个函数仅支持一个参数(除self外)用来接收序列中的元素。

内建函数\方法

先来看使用内建的函数或者方法处理的效果:

ls = ["a", "b", "c", "D", "E"]
# 直接排序,结果为['D', 'E', 'a', 'b', 'c']
print(sorted(ls))
# 使用lower,将所有元素转化为小写字母再排序['a', 'b', 'c', 'D', 'E']
# 因为lower是字符串的方法,所以这里要加上调用方为字符串类型
print(sorted(ls, key=str.lower))

自定义函数

既然可以使用内建的函数或者方法,那么当然也可以自定义函数,执行排序时,会对序列中的每一个元素依次调用我们指定的函数,然后把返回值拿来做比较。

# 例如我们想把列表中的数字按照个位的大小进行排序,那么就可以定义一个函数,返回一个整数的个位数
def gewei(num: int) -> int:
    return num % 10


ls = [991, 86, 3]
# 结果为[991, 3, 86]
print(sorted(ls, key=gewei))
# 当然,我们也可以写lamda表达式(匿名函数),结果是一样的
print(sorted(ls, key=lambda num: num % 10))

前面说到了,如果传入类作为key的参数,那么会依次将序列中的元素作为类构造函数的参数,然后将生成的对象作比较。

这里要提一点,对象作比较,实际上是调用类的__lt__或者__gt__方法,因此,类必须实现其中一个方法。

关于__lt__和__gt__方法

__lt__、__gt__分别表示:小于、大于,对应的操作符为:'<'、'>'。

1.当自定义类中两个方法都定义了时,'<'和'>'分别调用__lt__和__gt__方法;

2.当自定义类中定义了__lt__方法,未定义__gt__方法时,进行”>”比较也是调用__lt__方法,只是对调用值求反。

class Stu:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    # __lt__方法有两个参数,分别表示自身对象和其它对象,这种格式是固定的,__gt__也是一样
    # 这里我们定义,两个Stu对象比较时,age属性较小的一方更小
    def __lt__(self, other):
        return self.age < other.age


s1 = Stu("小明", 10)
s2 = Stu("小红", 12)
# 结果为True,如果类里没有实现__lt__或者__gt__方法,那这里就会报错
print(s1 < s2)

类作为key参数

上面定义的类构造函数需要接受两个参数,name和age,所以这样的类是不能作为key的参数值的,因为key是将序列中的每一个元素依次传入,所以类构造函数能且只能接受一个参数:

class Stu:
    def __init__(self, age):
        self.age = age

    def __lt__(self, other):
        # 这里我故意反着来,年龄比较大的一方反而更小
        return self.age > other.age


ls = [10, 20, 11, 4, 9, 23]
# 虽然默认为升序,但是比较规则里是年龄更大的对象更小,所以年龄大的会排前面
# 结果为[23, 20, 11, 10, 9, 4]
print(sorted(ls, key=Stu))

 

标签:__,函数,age,lt,ls,key,sorted,self
From: https://www.cnblogs.com/haruyuki/p/16758134.html

相关文章

  • 概率生成函数 (PGF)
    1.概述取值处概率的生成函数。\(F(1)=1,F'(1)=E\)2.分析设\(F(i)\)为\(i\)时刻结束概率的生成函数,\(G(i)\)为\(i\)时刻未结束概率的生成函数,那么有:\[f_i+g_i=g......
  • 算法学习笔记(数学):数论分块 + 容斥原理 + 莫比乌斯函数
    算法学习笔记(数学):数论分块+容斥原理+莫比乌斯函数这篇文章主要是要讲一道题目(链接在这里)以及梳理一下数论分块,莫比乌斯函数,容斥原理这些知识。先介绍下知识点吧qwq......
  • 8.函数上
    函数函数的原型和调用在使用函数前必须定义或者声明函数doublecircle(doubler);intmain(){ doublelength=circle(10);printf("length=%f\n",length......
  • C语言:三角函数的参数为弧度,通常的角度值需要转化为弧度
    #include<stdio.h>#include<math.h>//三角函数的参数为弧度,是角度必须转化为弧度//3.14=180,1度=3.14/180,转化方法:(3.14/180)*角度值main(){floata,b,c;......
  • 对于函数递归的理解
    递归的代码操作就是在自己未完成的函数之中调用自己这样看起来是并不合理的,因为在一个为完成的东西之中使用他自己,是不太现实的但是如果从代码执行的逻辑来进行理解的话,......
  • 网络字节序与主机字节序的转换函数实践。
    为了进行转换,BSDsocket提供了转换的函数,有下面四个:(BSDSocket是UNIX系统中通用的网络接口,它不仅支持各种不同的网络类型,而且也是一种内部进程之间的通信机制)头文件:#inc......
  • 分组函数
    多行处理函数多行处理函数的特点:输入多行,最终输出一行count计数sum求和avg平均值max最大值min最小值注意:分组函数在使用的时候必须先进行分组,然后才能用如......
  • SQL 标量函数-----日期函数 day() 、month()、year()
      selectday(createtime)fromlife_unite_product    --取时间字段的天值selectmonth(createtime)fromlife_unite_product  --取时间字段的月值selec......
  • JZOJ 7685. 【2022.10.06冲剌NOIP2022模拟】奇怪的函数(function)
    \(\text{Solution}\)观察到关于\(x\)的函数在\(n\)个操作之后一定是这样的:一段水平直线加上一段斜率为\(1\)的直线再加上一段水平直线于是线段树维护这个分段函数......
  • 2022牛客OI赛前集训营-提高组(第一场) 奇怪的函数 根号很好用
    奇怪的函数考虑暴力,每次查询\(O(n)\)扫所有操作,修改\(O(1)\)这启发我们平衡复杂度,考虑分块。观察题目性质,可以发现,经过若干次操作后得到的结果一定是一个关于\(x\)的分......