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. SVN提交到服务器退回至指定版本(撤销操作)

    一.撤销已提交内容如果不小心把修改错误的文件提交到服务器上去了 可对其进行复原(指定单个文件撤销) 解决方法: 查看修改的日志 查看错误提交的文件 可以查看到这个文件改了什么 复原此版本作出的修改 然 ...

  2. cximage菜单(Mirror)

    // ID_CXIMAGE_MIRROR 文件:CxImage\demo\demoDoc.cpp 菜单项:cximage->Mirror ON_COMMAND(ID_CXIMAGE_MIRROR ...

  3. js提交数据

    一.from表单提交 <form action="" method="post" enctype="multipart/form-data&qu ...

  4. 这里记录一下我个人对AXI4主从模块的理解(这些理解主要来自阅读 Xilinx AXI_FULL_M_module 源码)

    先只考虑读请求: 以取指模块和内存模块为例,取指模块是发出请求的模块,因此为 Master,属于AXI4MasterModule:内存模块是响应请求的模块,因此为 Slave,属于AXI4SlaveM ...

  5. 解决React 安装 antd 后出现的Module not found: Can't resolve './locale' in '...rc-picker/node-modules.....'一系列问题问题

    最近看到很多小伙伴发现了antd的这个问题,试用了网上的办法不行,我自己想了一种可行的方法,大家可以试一试. 有位大佬用了yarn eject 方式 ,通过暴露config配置,在config.web ...

  6. 流(stream)如何理解?

    前言 如果你搜索输入输出函数,那么你会看到各种各样的流.那么这个流到底是什么东西呢,本文将形象地类比介绍通用的流. 怎样理解通用的流 流,顾名思义就是像水流一样可以流动的事物,可以在不同的领域来去自如 ...

  7. vue2 项目引入Fontawesome

    官网: https://fontawesome.com/ 1.安装 `` `powershell npm i --save @fortawesome/fontawesome-svg-core Usin ...

  8. Open vSwitch虚拟交换机实践

    实验2:Open vSwitch虚拟交换机实践 (一)基本要求 1.ovs-vsctl基础操作实践: 创建OVS交换机,完成相关要求后查看网络状态与端口信息: 2.使用Mininet搭建的SDN拓扑, ...

  9. python 多进程和异步io的有机结合 Error in atexit._run_exitfuncs

    众所周知,python的多线程开发在GIL(全局器解释锁)下饱受诟病,在单核模式下搞多线程对效率的提升相当有限.于是大家的共识就是搞io密集的程序,建议采用多线程,计算密集型的程序就搞多进程.近期的一 ...

  10. Office2021专业增强版激活

    1.以管理员权限运行win+R输入CMD,进入命令行界面,输入以下命令 32位系统输入:cd /d %ProgramFiles(x86)%\Microsoft Office\Office16 64位系 ...