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. AI 能多强「GitHub 热点速览」

    不知道 AI 在你那边是什么样的具象,在我这就是各种搞图:从给线稿图上色,到直接给你生成一张小色图,AI 最近是真出风头,本周热点速览也收录了 2 个 AI 项目,也和图像有关.还有一个和 AI 相关 ...

  2. Qt-FFmpeg开发-视频播放【软解码 + OpenGL显示RGB图像】(3)

    Qt-FFmpeg开发-视频播放[软解码 + OpenGL显示RGB图像] 目录 Qt-FFmpeg开发-视频播放[软解码 + OpenGL显示RGB图像] 1.概述 2.实现效果 3.FFmpeg软 ...

  3. 数据转换工具DBT介绍及实操

    一.什么是DBT dbt (data build tool)是一款流行的开源数据转换工具,能够通过 SQL 实现数据转化,将命令转化为表或者视图,提升数据分析师的工作效率.dbt 主要功能在于转换数据 ...

  4. LeetCode-846 一手顺子

    来源:力扣(LeetCode)链接:https://leetcode-cn.com/problems/hand-of-straights 题目描述 Alice 手中有一把牌,她想要重新排列这些牌,分成 ...

  5. MyBatisPlus(springBoot版)-尚硅谷

    Pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...

  6. 分时问候——时间类、if语句

    import java.time.LocalTime; public class Hello { public static void main(String[] args) { LocalTime ...

  7. 179. 最大数 (Medium)

    问题描述 179. 最大数 (Medium) 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数. 注意: 输出结果可能非常大,所以你需要返回一个字符串而不是整数 ...

  8. Windows环境同时安装多个版本的Python解释器(python2和python3)

    https://blog.csdn.net/qq_21583139/article/details/125881382 出现问题: 更新pip 操作后出现,pip报错,应该是升级到最新pip版本然后和 ...

  9. k8s-master 重启之后报错

    The connection to the server 192.168.1.30:6443 was refused - did you specify the right host or port? ...

  10. Tech&W_STU_Resource_bookmark

    整合资料 1 architecture: Enterprise integration patterns : https://www.enterpriseintegrationpatterns.com ...