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相关推荐

  1. 冒泡排序 python内置_除了冒泡排序,你知道Python内建的排序算法吗?

    选自hackernoon,作者:Brandon Skerritt,机器之心编译,参与:高璇.思源.对于编程算法,可能很多读者在学校第一个了解的就是冒泡排序,但是你真的知道 Python 内建排序算法 ...

  2. python 生成001开始的序号_你知道嘛:Python内建序列通用操作有6种实现方法(赶快收藏)...

    本文内容主要介绍了Python内建序列通用操作6种实现方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下!!! 数据结构式通过某种方式(例如对元素进 ...

  3. python内建常用函数

    #标题1# # python内建常用函数# #python内建常用函数 在这里插入图片描述 ![在这里插入图片描述](https://img-blog.csdnimg.cn/2020030211175 ...

  4. python内建方法

    在help文档中查看方法的参数时: 在'/'之前的参数都是位置参数 在'/'与'*'之间的参数可以被用作位置参数和关键字参数 在'*'之后的参数只能是关键字参数 我们可以使用dir(__builtin ...

  5. python内建集合模块collections功能,计数,有序,双向队列

    一.官方介绍 这个模块实现了特定目标的容器,以提供Python标准内建容器 dict , list , set , 和 tuple 的替代选择. namedtuple() 创建命名元组子类的工厂函数 ...

  6. python 内建比较函数详解

    http://blog.sina.com.cn/s/blog_5357c0af01011392.html 我们经常需要比较两个对象,使用自定义的函数是个方法,但不直观 故而我们常常使用比较运算符来直接 ...

  7. python内建模块_Python 内建模块

    1.内建模块: 在Python中,有一个内建模块,该模块中有一些常用函数;而该模块在Python启动后.且没有执行程序员所写的任何代码前,Python会首先加载该内建函数到内存.另外,该内建模块中的功 ...

  8. python内置排序算法_2021-01-05 排序算法(Python语言实现)

    1.二分查找 def binary_search(li,val): left = 0 right = len(li) - 1 while left <= right: #候选区有值 mid = ...

  9. python内建时间模块 time和datetime

    时间模块 UTC(Coordinated Universal Time,世界协调时)亦即格林威治天文时间,世界标准时间.在中国为UTC+8.DST(Daylight Saving Time)即夏令时. ...

最新文章

  1. AIX如何查看文件系统分布在哪个物理磁盘上
  2. matlab显示的图片,手动保存时四周有白边
  3. 鲁东大学计算机王跃,鲁东大学学子在“程序设计天梯赛”中取得优异成绩
  4. Linux下查看进程对应的命令绝对路径
  5. android md 控件,Android基本UI控件.md
  6. php 数组区删除重复的,php – 从数组中删除重复的项目
  7. python之路alex_Python之路--python基础2
  8. 【渝粤教育】国家开放大学2018年春季 0689-21T老年心理健康 参考试题
  9. 临时号码,接收短信验证码
  10. 数字化时代,如何做好用户体验与应用性能管理
  11. 手机丢了微信聊天记录怎么恢复?别担心,教你一招找回
  12. ROS学习总结十二:给自己的机器人添加传感器
  13. request库单一视频下载
  14. Python_文本分析入门_SnowNLP(1)
  15. Java8 ConcurrentHashMap的get()方法真的不需要加锁吗?
  16. 【狼窝乀野狼】Excel那些事儿
  17. Java语言的特性和优点
  18. 花生壳http更新协议
  19. SqlSugar的使用
  20. 基于C#实现的学生考试系统

热门文章

  1. vim 替换文本指令
  2. element-联动下拉框
  3. android监听耳机,Android监听耳机按键事件
  4. 深度学习主机环境配置: Ubuntu16.04+Nvidia GTX 1080/980ti+CUDA8.0
  5. ENSP华为模拟器:基础命令及简写
  6. java命名规则与规范
  7. java — 多线程设计模式
  8. linux下rename用法--批量重命名
  9. pro缺点和不足 一加7t_一加7T与OPPO Reno Ace 各有优势与缺点
  10. jsp 的 4 种作用域?