python的排序问题
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的排序问题的更多相关文章
- Python字典排序问题
字典的问题 navagation: 1.问题来源 2.dict的学习 *3.numpy的应用 1.问题来源 在做cs231n,assigment1-kNN实现的时候,需要对一个列表中的元素进行计数,并 ...
- Python中的各种排序问题
小书匠python排序 本章目录,快速浏览所需内容: 基本的排序 1.列表(list) 1.1按列表元素大小排序 1.2按列表元素的属性 2.字典(dictory) 3.元组(tuple)排序 3.1 ...
- Python中os.listdir的排序问题
上周应别人要求,使用python批量修改文件名称.文件名有规律,当时就用了一个函数直接精确的用文件名替换了.后来想直接可以用listdir来遍历每个文件来修改更加通用一些.但是看了os.listdir ...
- 对Python中函数参数类型及排序问题,三个方面的总结
Python中函数的参数问题有点复杂,主要是因为参数类型问题导致的情况比较多,下面来分析一下. 参数类型:缺省参数,关键字参数,不定长位置参数,不定长关键字参数. 其实总共可以分为 位置参数和关键字参 ...
- python基础知识-列表的排序问题
def main(): f=['orange','zoo','apple','internationalization','blueberry'] #python 内置的排序方式默认为升序(从小到大) ...
- python 列表、字典多排序问题
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/justin051/article/det ...
- python 层次索引交换级别以及排序问题
- python 中各种数据类型的排序问题
list #按照list的第二键值排序 disP2P = [[1,2,3],[2,3,4],[4,5,6]] disP2P = sorted(disP2P,key = lambda x:x[2]) s ...
- Python从破门而入到夺门而出
MD版网盘备份: 链接: https://pan.baidu.com/s/1kVJNRSz 密码: agxt 基于<简明Python教程> 一.Python概览 1.使用PyCharm是非 ...
- python面试大全
问题一:以下的代码的输出将是什么? 说出你的答案并解释. class Parent(object): x = 1 class Child1(Parent): pass class Child2(Par ...
随机推荐
- Android ViewModel,LiveData 简要分析
ViewModel: 负责为关联UI(activity/fragment)进行数据管理,业务逻辑处理.不直接持有view引用,不对UI进行访问调用操作 对外通过暴露Livedata方式响应处理结果 L ...
- Day 23 23.2.1:微信公众平台案例
微信公众平台案例 注意:接下来将的内容,请忽视具体网站,重点专注逆向的分析思路! 接下来就是爬什么网站,什么数据,什么形式都统统不重要!重点是分析思路 微信公众平台案例 url:https://mp. ...
- JDK8在xp安装办法
jdk默认不支持xp,用到了后来的api,直接没法安装. 具体安装步骤: 1.用7-zip打开jdk8的版本8u231之前的版本. 2.导航到 .rsrc\1033\JAVA_CAB10\111把里面 ...
- 判断js对象每个字段是否为空
for(var key in obj) { if (!obj[key])return; }
- CSS布局display值inline、block、inline-block区别
inline前后不会有换行,block前后会有换行,inline-block前后不会有换行,但内部会换行且可以设置高宽.,如下图所示:
- redis 单节点迁移到集群 redis-shake
1.迁移 1.1.同步到单节点 redis-shake下载 release-v2.1.2-20220329.tar.gz #redis cluster 某一个节点 服务器安装redis-shak ...
- Mac 远程 屏幕共享 screen sharing
屏幕共享可以用于在局域网中控制另一台 Mac,也能通过 iMessage 在广域网环境下创建彼此的连接,用来指导和解决问题非常方便. 通过 Apple ID 来创建连接 1,Command+空格键 ...
- express的使用:web开发(四)
1.开发模式 1.服务端渲染 2.前后端分离 2.身份认证 1.服务端渲染推荐使用session认证机制 2.前端后端分离建议使用JWT认证机制 3.http协议的无状态性 4.cookie特性 1. ...
- vue 传参跳转 iview、element组件
方法一1.本页vue跳转链接. <router-link :to="{path:'/details_page',query: {type:items.types,id: items.i ...
- TPS,RPS,QPS,RT的区别
以下是对性能中各项指标的解释: 1.TPS:Transaction Per Second,服务器每秒处理事务数,是衡量系统性能的一个非常重要的指标. 计算公式:TPS= 总请求数 / 总时间. ...