python 内建排序 HOW TO
list.sort()与sorted()
python 有两个内建排序函数:一个是list.sort(),对调用该函数的list进行原地排序;另一个是sorted(),可以对任意迭代器进行排序,返回list类型的序列。二者有两个区别。
第一,list.sort()没有返回值,只对list原地排序;而sorted()将排序后序列作为新list返回,如下实例:
>>> sorted([5, 2, 3, 1, 4]) [1, 2, 3, 4, 5]>>> a = [5, 2, 3, 1, 4] >>> a.sort() >>> a [1, 2, 3, 4, 5]
第二,list.sort()只应用于list,而sorted()可用于任意迭代器,如下实例:
>>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]
另外,二者都有相同参数:1.key 2.reverse 3.cmp,并且使用方法相同,下面通过sorted()进行详细说明
key参数的使用
基本说明:
key参数指定一个函数,这个函数的实参为每个迭代器的item,经过该函数运算,返回值为每个item中需要进行对比的项(key),如下实例:
>>> sorted("This is a test string from Andrew".split(), key=str.lower) ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
简单说,key参数值必须是一个函数,且这个函数只有一个参数,并且返回一个key值,作为比较使用。
使用实例说明:
通常情况下,对于复杂结构进行排序,通常使用索引作为比较的key,例如:
>>> student_tuples = [('john', 'A', 15),('jane', 'B', 12),('dave', 'B', 10), ] >>> sorted(student_tuples, key=lambda student: student[2]) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
类似的排序方式,也可以用于类,例如:
>>> class Student:def __init__(self, name, grade, age):self.name = nameself.grade = gradeself.age = agedef __repr__(self):return repr((self.name, self.grade, self.age))>>>>>> student_objects = [Student('john', 'A', 15),Student('jane', 'B', 12),Student('dave', 'B', 10), ] >>> sorted(student_objects, key=lambda student: student.age) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
使用Operator模块
由于以上使用key参数的方式十分普遍,python提供了相关函数,使以上方式的使用更加简单快捷。
operator模块提供了 operator.itemgetter(),operator.attrgetter()函数,在 Python 2.5以后还提供了operator.methodcaller() 函数。使用这些函数可以让上节描述的排序方法更加快捷方便:
>>> from operator import itemgetter, attrgetter>>>>>> sorted(student_tuples, key=itemgetter(2)) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]>>>>>> sorted(student_objects, key=attrgetter('age')) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
operater模块提供的函数,可以进行多级排序. 如下实例, 先以grade排序,再以 age排序:
>>> sorted(student_tuples, key=itemgetter(1,2)) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]>>>>>> sorted(student_objects, key=attrgetter('grade', 'age')) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
operator.methodcaller()函数可以调用方法,操作需要比较的item后,然后对item进行比较。如下实例,str.count()方法对每个item的感叹号进行统计,按照包含感叹号的多少进行排序:
>>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!'] >>> sorted(messages, key=methodcaller('count', '!')) ['standby', 'hurry!', 'immediate!!', 'critical!!!']
reverse参数的使用
reverse参数很好理解,如果reverse=True,将以降序排序,如下实例:
>>> sorted(student_tuples, key=itemgetter(2), reverse=True) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]>>>>>> sorted(student_objects, key=attrgetter('age'), reverse=True) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
cmp参数的使用(不推荐)
在python2.4以前,排序没有key参数,所有进行自定义排序,使用的都是cmp参数。而在python 3开始,就没有cmp参数了,另外cmp参数没有key运行得快,所以这里只做简单说明,建议大家尽量使用key参数进行排序
cmp参数值是一个有两个参数的函数,该函数参数的实参也是需要比较的item,通过该函数进行计算,返回的结果如果为负数,证明item1<item2,若为0,证明item1=item2,为正数,证明item1>item2。如下例子:
>>> def numeric_compare(x, y):return x - y >>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare) [1, 2, 3, 4, 5]
刚才说道python3.x不支持cmp参数,如何将python2.x程序迁移到python3.x呢?使用下述方法:
def cmp_to_key(mycmp):'Convert a cmp= function into a key= function'class K(object):def __init__(self, obj, *args):self.obj = objdef __lt__(self, other):return mycmp(self.obj, other.obj) < 0def __gt__(self, other):return mycmp(self.obj, other.obj) > 0def __eq__(self, other):return mycmp(self.obj, other.obj) == 0def __le__(self, other):return mycmp(self.obj, other.obj) <= 0def __ge__(self, other):return mycmp(self.obj, other.obj) >= 0def __ne__(self, other):return mycmp(self.obj, other.obj) != 0return K
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric)) [5, 4, 3, 2, 1]
在python2.7以后,functools.cmp_to_key() 可直接通过functools进行调用
另外一些说明
一、为类组成的列表,提供默认的排序方法
在类中将排序中作为key的属性,加入相关比较的方法中,如下:
>>> Student.__eq__ = lambda self, other: self.age == other.age >>> Student.__ne__ = lambda self, other: self.age != other.age >>> Student.__lt__ = lambda self, other: self.age < other.age >>> Student.__le__ = lambda self, other: self.age <= other.age >>> Student.__gt__ = lambda self, other: self.age > other.age >>> Student.__ge__ = lambda self, other: self.age >= other.age >>> sorted(student_objects) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
一般以实现这六种比较方法为佳,另外可以使用functools.total_ordering()修饰,可以简化代码量
二、key参数的另一种用法
key参数不只依赖被排序的实例,可以使用额外的实例作为key。如下例子:student 成绩存在一个字典中, 此字典可以用于给另一个包含student姓名的list排序::
>>> students = ['dave', 'john', 'jane'] >>> grades = {'john': 'F', 'jane':'A', 'dave': 'C'} >>> sorted(students, key=grades.__getitem__) ['jane', 'dave', 'john']
参考:
http://docs.python.org/2/howto/sorting.html
python 内建排序 HOW TO相关推荐
- 冒泡排序 python内置_除了冒泡排序,你知道Python内建的排序算法吗?
选自hackernoon,作者:Brandon Skerritt,机器之心编译,参与:高璇.思源.对于编程算法,可能很多读者在学校第一个了解的就是冒泡排序,但是你真的知道 Python 内建排序算法 ...
- python 生成001开始的序号_你知道嘛:Python内建序列通用操作有6种实现方法(赶快收藏)...
本文内容主要介绍了Python内建序列通用操作6种实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下!!! 数据结构式通过某种方式(例如对元素进 ...
- python内建常用函数
#标题1# # python内建常用函数# #python内建常用函数 在这里插入图片描述 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020030211175 ...
- python内建方法
在help文档中查看方法的参数时: 在'/'之前的参数都是位置参数 在'/'与'*'之间的参数可以被用作位置参数和关键字参数 在'*'之后的参数只能是关键字参数 我们可以使用dir(__builtin ...
- python内建集合模块collections功能,计数,有序,双向队列
一.官方介绍 这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择. namedtuple() 创建命名元组子类的工厂函数 ...
- python 内建比较函数详解
http://blog.sina.com.cn/s/blog_5357c0af01011392.html 我们经常需要比较两个对象,使用自定义的函数是个方法,但不直观 故而我们常常使用比较运算符来直接 ...
- python内建模块_Python 内建模块
1.内建模块: 在Python中,有一个内建模块,该模块中有一些常用函数;而该模块在Python启动后.且没有执行程序员所写的任何代码前,Python会首先加载该内建函数到内存.另外,该内建模块中的功 ...
- python内置排序算法_2021-01-05 排序算法(Python语言实现)
1.二分查找 def binary_search(li,val): left = 0 right = len(li) - 1 while left <= right: #候选区有值 mid = ...
- python内建时间模块 time和datetime
时间模块 UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间.在中国为UTC+8.DST(Daylight Saving Time)即夏令时. ...
最新文章
- AIX如何查看文件系统分布在哪个物理磁盘上
- matlab显示的图片,手动保存时四周有白边
- 鲁东大学计算机王跃,鲁东大学学子在“程序设计天梯赛”中取得优异成绩
- Linux下查看进程对应的命令绝对路径
- android md 控件,Android基本UI控件.md
- php 数组区删除重复的,php – 从数组中删除重复的项目
- python之路alex_Python之路--python基础2
- 【渝粤教育】国家开放大学2018年春季 0689-21T老年心理健康 参考试题
- 临时号码,接收短信验证码
- 数字化时代,如何做好用户体验与应用性能管理
- 手机丢了微信聊天记录怎么恢复?别担心,教你一招找回
- ROS学习总结十二:给自己的机器人添加传感器
- request库单一视频下载
- Python_文本分析入门_SnowNLP(1)
- Java8 ConcurrentHashMap的get()方法真的不需要加锁吗?
- 【狼窝乀野狼】Excel那些事儿
- Java语言的特性和优点
- 花生壳http更新协议
- SqlSugar的使用
- 基于C#实现的学生考试系统