python的排序方法有两个

1 nums.sort() # 原数组上排序, 没有返回值, nums变为有序
2 # 或者
3 nums = sorted(nums) # 原数组不变, 会返回一个排好序的新数组

那么如何自定义排序规则呢?

自定义排序规则:

假设现在有这么个问题,有n个学生, 每个学生有一个数学成绩,有一个语文成绩,

要求按照总分从高到低排序,分数一样,再按照数学成绩从低到高, 再一样则按照语文成绩从高到低。

这个问题该怎么解决呢?

对于java, 我们有两种方式,一种是自定义Comparator比较器, 另一种是类实现Comparable接口。

首先我们定义一个学生类:

1 class Student:
2 def __init__(self, math, chinese):
3 self.math = math # 数学成绩
4 self.chinese = chinese # 语文成绩
5
6 # 总分
7 def sum(self):
8 return self.math + self.chinese

python实现自定义排序,比较灵活和简单, 因为sort方法可以接受一个key作为参数, 这个key接受一个函数,

这个函数接受一个参数, 返回一个值, 那么最终就是用这个函数返回的值来比较大小, 从而实现排序。

所以想要自定义排序,我们可以传入一个恰当的函数作为key的值。

比如对于上面提出的问题,排序可以这么写:

1 def cmp(e):
2 return (-e.sum(), e.math, -e.chinese)
3
4 students.sort(key=cmp)

首先我们定义一个函数cmp, 这个函数接收一个参数, 返回一个值,并将其赋值给key。

那么对students数组排序,实际上相当于对每个数组元素,被cmp函数作用一遍之后的值进行排序。

也就是相当于是对这些返回的元祖进行排序。 然后观察元祖的返回值, 第一个是-e.sum(), 元祖默认是从小到大按数值大小进行排序的,所有就实现了

对学生数组按总分进行从高到低排序了;总分相同,就按照数学成绩从低到高排序了

完整代码如下:

 1 class Student:
2 def __init__(self, math, chinese):
3 self.math = math # 数学成绩
4 self.chinese = chinese # 语文成绩
5
6 # 总分
7 def sum(self):
8 return self.math + self.chinese
9
10 def __str__(self):
11 return "总分:{},数学:{},语文:{}".format(self.sum(), self.math, self.chinese)
12
13 n = int(input())
14 students = [None for i in range(n)] # 多个Student对象
15 for i in range(n):
16 a, b = map(int, input().split())
17 students[i] = Student(a, b)
18
19 def cmp(e):
20 return (-e.sum(), e.math, -e.chinese)
21
22 students.sort(key=cmp)
23 print(*students, sep='\n')

测试结果如下:

5
60 70
70 60
80 60
75 90
90 75
总分:165,数学:75,语文:90
总分:165,数学:90,语文:75
总分:140,数学:80,语文:60
总分:130,数学:60,语文:70
总分:130,数学:70,语文:60

对于key函数, 我们都是接受一个参数,返回一个值,所以这个函数往往比较简单,所以可以考虑用lambda表达式

可以改成如下代码:

students.sort(key=lambda e: (-e.sum(), e.math, -e.chinese))

基本上用这种方法可以解决绝大部分排序问题

重载运算符

在java中我们可以实现一个Comparable接口来让对象具备可比较性。在python当中我们可以通过重载运算符的方式来实现对象之间的可比较性。

python中可以重载的运算符:

dir(object)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__
', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
'__str__', '__subclasshook__']

通过dir(object)我们可以看到python类当中有很多双下划线开头的方法,这些都是内置方法,有特殊用途。

其中:

__gt__ 对应  大于号 >

__lt__ 对应 小于号 <

__ge__ 对应 大于等于号 >=

__le__ 对应小于等于号 <=

只要重载了其中一个运算符,那么这个类的对象就具备了可比较性

以上文的学生类为例:

完整代码如下:

 1 class Student:
2 def __init__(self, math, chinese):
3 self.math = math # 数学成绩
4 self.chinese = chinese # 语文成绩
5
6 # 总分
7 def sum(self):
8 return self.math + self.chinese
9
10 def __lt__(self, other):
11 if self.sum() == other.sum():
12 if self.math == other.math:
13 return self.chinese > other.chinese
14 else:
15 return self.math < other.math
16 else:
17 return self.sum() > other.sum()
18
19 def __str__(self):
20 return "总分:{},数学:{},语文:{}".format(self.sum(), self.math, self.chinese)
21
22 n = int(input())
23 students = [None for i in range(n)] # 多个Student对象
24 for i in range(n):
25 a, b = map(int, input().split())
26 students[i] = Student(a, b)
27
28 students.sort()
29 print(*students, sep='\n')

测试结果如下:

5
60 70
70 60
80 60
75 90
90 75
总分:165,数学:75,语文:90
总分:165,数学:90,语文:75
总分:140,数学:80,语文:60
总分:130,数学:60,语文:70
总分:130,数学:70,语文:60

重载了小于号运算符 < 后, 任意两个学生对象可以直接进行比较 如 : s1 < s2, 其中s1和s2是学生对象。

那么自然就知道如何比较大小了, 这时候sort函数可以不用传入key,也可以按我们的自定义规则排序了

python的排序问题的更多相关文章

  1. Python字典排序问题

    字典的问题 navagation: 1.问题来源 2.dict的学习 *3.numpy的应用 1.问题来源 在做cs231n,assigment1-kNN实现的时候,需要对一个列表中的元素进行计数,并 ...

  2. Python中的各种排序问题

    小书匠python排序 本章目录,快速浏览所需内容: 基本的排序 1.列表(list) 1.1按列表元素大小排序 1.2按列表元素的属性 2.字典(dictory) 3.元组(tuple)排序 3.1 ...

  3. Python中os.listdir的排序问题

    上周应别人要求,使用python批量修改文件名称.文件名有规律,当时就用了一个函数直接精确的用文件名替换了.后来想直接可以用listdir来遍历每个文件来修改更加通用一些.但是看了os.listdir ...

  4. 对Python中函数参数类型及排序问题,三个方面的总结

    Python中函数的参数问题有点复杂,主要是因为参数类型问题导致的情况比较多,下面来分析一下. 参数类型:缺省参数,关键字参数,不定长位置参数,不定长关键字参数. 其实总共可以分为 位置参数和关键字参 ...

  5. python基础知识-列表的排序问题

    def main(): f=['orange','zoo','apple','internationalization','blueberry'] #python 内置的排序方式默认为升序(从小到大) ...

  6. python 列表、字典多排序问题

    版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/justin051/article/det ...

  7. python 层次索引交换级别以及排序问题

  8. python 中各种数据类型的排序问题

    list #按照list的第二键值排序 disP2P = [[1,2,3],[2,3,4],[4,5,6]] disP2P = sorted(disP2P,key = lambda x:x[2]) s ...

  9. Python从破门而入到夺门而出

    MD版网盘备份: 链接: https://pan.baidu.com/s/1kVJNRSz 密码: agxt 基于<简明Python教程> 一.Python概览 1.使用PyCharm是非 ...

  10. python面试大全

    问题一:以下的代码的输出将是什么? 说出你的答案并解释. class Parent(object): x = 1 class Child1(Parent): pass class Child2(Par ...

随机推荐

  1. ASP.NET Core - 依赖注入(三)

    4. 容器中的服务创建与释放 我们使用了 IoC 容器之后,服务实例的创建和销毁的工作就交给了容器去处理,前面也讲到了服务的生命周期,那三种生命周期中对象的创建和销毁分别在什么时候呢.以下面的例子演示 ...

  2. 开源分布式任务调度系统就选:DolphinScheduler

    分布式任务调度这个话题是每个后端开发和大数据开发都会接触的话题.因为应用场景的广泛,所以有很多开源项目专注于解决这类问题,比如我们熟知的xxl-job. 那么今天要给大家推荐的则是另一个更为强大的开源 ...

  3. Dynamics365 DOC

    Sample: Early-bound table operationshttps://docs.microsoft.com/en-us/powerapps/developer/data-platfo ...

  4. mybatis动态标签——choose、when、otherwise

    <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "- ...

  5. go语言初记

    快速了解 http://go-tour-zh.appspot.com/welcome/1 (可以需要爬墙) 下面记录下了解go的过程,特别记录下与你脑子里原有"观念"不同的地方: ...

  6. 03-python基本数据类型详解

    python基本数据类型详解 一.整型int 存储年龄,身份证号等 age = 18 id = 0000001 # 注:可以使用type关键字查看变量的数据类型 print(type(age)) # ...

  7. 【Direct3D 12】配置编译环境

    创建桌面应用程序 使用Visual Studio Community 2019创建一个桌面应用程序. 配置SDK版本.头文件.依赖库 右键单击创建的项目名称,选择Properties. 在Config ...

  8. 2022-05-26内部群每日三题-清辉PMP

    1.在执行关键路径上的一项活动时,职能主管将涉及这个活动的两个项目资源调去支持解决某个应急情况,项目经理应该怎么做? A.实施应急计划 B.快速跟进关键路径 C.与职能经理协商分配替代资源 D.将该问 ...

  9. 挂上burpsuite代理之后显示505 HTTP Version Not Supported 解决方法

    505 HTTP Version Not Supported  什么意思呢? HTTP505状态码代表的意思是 服务器不支持的HTTP版本,即 HTTP 505 HTTP Version Not Su ...

  10. ubuntu下升级gcc11环境

    使用ppa源升级 官网地址: https://launchpad.net/ ppa toolchan/test地址: https://launchpad.net/~ubuntu-toolchain-r ...