python sort()、sorted()

python sort、sorted排序

       这篇文章主要介绍了python sort、sorted高级排序技巧,本文讲解了基础排序、升序和降序、排序的稳定性和复杂排序、cmp函数排序法等内容.
      python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列。

1)排序基础
       简单的升序排序是非常容易的。只需要调用sorted()方法。它返回一个新的list,新的list的元素基于小于运算符(__lt__)来排序。
代码如下:
>>> sorted([5, 2, 3, 1, 4])
[1, 2, 3, 4, 5]

       也可以使用list.sort()方法来排序,此时list本身将被修改。通常此方法不如sorted()方便,但是如果你不需要保留原来的list,此方法将更有效。
代码如下:
>>> 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]


2)key参数/函数
       从python2.4开始,list.sort()和sorted()函数增加了key参数来指定一个函数,此函数将在每个元素比较前被调用。 例如通过key指定的函数来忽略字符串的大小写:
代码如下:
>>> sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

       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 = name
                self.grade = grade
                self.age = age
        def __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)]


3)Operator 模块函数
       上面的key参数的使用非常广泛,因此python提供了一些方便的函数来使得访问方法更加容易和快速。operator模块有itemgetter,attrgetter,从2.6开始还增加了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)]

       operator模块还允许多级的排序,例如,先以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)]


4)升序和降序
       list.sort()和sorted()都接受一个参数reverse(True or False)来表示升序或降序排序。例如对上面的student降序排序如下:
代码如下:
>>> 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)]


5)排序的稳定性和复杂排序
       从python2.2开始,排序被保证为稳定的。意思是说多个元素如果有相同的key,则排序前后他们的先后顺序不变。
代码如下:
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=itemgetter(0))
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

注意:在排序后'blue'的顺序被保持了,即'blue', 1在'blue', 2的前面。
        更复杂地你可以构建多个步骤来进行更复杂的排序,例如对student数据先以grade降序排列,然后再以age升序排列。
代码如下:
>>> s = sorted(student_objects, key=attrgetter('age'))     # sort on secondary key
>>> sorted(s, key=attrgetter('grade'), reverse=True)       # now sort on primary key, descending
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]


6)最老土的排序方法-DSU
       我们称其为DSU(Decorate-Sort-Undecorate),原因为排序的过程需要下列三步:
                      第一:对原始的list进行装饰,使得新list的值可以用来控制排序;
                      第二:对装饰后的list排序;
                      第三:将装饰删除,将排序后的装饰list重新构建为原来类型的list;
 例如,使用DSU方法来对student数据根据grade排序:
>>> decorated = [(student.grade, i, student) for i, student in enumerate(student_objects)]
>>> decorated.sort()
>>> [student for grade, i, student in decorated]               # undecorate
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
上面的比较能够工作,原因是tuples是可以用来比较,tuples间的比较首先比较tuples的第一个元素,如果第一个相同再比较第二个元素,以此类推。
       并不是所有的情况下都需要在以上的tuples中包含索引,但是包含索引可以有以下好处:
                    第一:排序是稳定的,如果两个元素有相同的key,则他们的原始先后顺序保持不变;
                    第二:原始的元素不必用来做比较,因为tuples的第一和第二元素用来比较已经是足够了。
 此方法被RandalL.在perl中广泛推广后,他的另一个名字为也被称为Schwartzian transform。
        对大的list或list的元素计算起来太过复杂的情况下,在python2.4前,DSU很可能是最快的排序方法。但是在2.4之后,上面解释的key函数提供了类似的功能。
 
7)其他语言普遍使用的排序方法-cmp函数
       在python2.4前,sorted()和list.sort()函数没有提供key参数,但是提供了cmp参数来让用户指定比较函数。此方法在其他语言中也普遍存在。
       在python3.0中,cmp参数被彻底的移除了,从而简化和统一语言,减少了高级比较和__cmp__方法的冲突。
       在python2.x中cmp参数指定的函数用来进行元素间的比较。此函数需要2个参数,然后返回负数表示小于,0表示等于,正数表示大于。例如:
代码如下:
>>> def numeric_compare(x, y):
        return x - y
>>> sorted([5, 2, 4, 1, 3], cmp=numeric_compare)
[1, 2, 3, 4, 5]

或者你可以反序排序:
代码如下:
>>> def reverse_numeric(x, y):
        return y - x
>>> sorted([5, 2, 4, 1, 3], cmp=reverse_numeric)
[5, 4, 3, 2, 1]

当我们将现有的2.x的代码移植到3.x时,需要将cmp函数转化为key函数,以下的wrapper很有帮助:
代码如下:
def cmp_to_key(mycmp):
    'Convert a cmp= function into a key= function'
    class K(object):
        def __init__(self, obj, *args):
            self.obj = obj
        def __lt__(self, other):
            return mycmp(self.obj, other.obj) < 0
        def __gt__(self, other):
            return mycmp(self.obj, other.obj) > 0
        def __eq__(self, other):
            return mycmp(self.obj, other.obj) == 0
        def __le__(self, other):
            return mycmp(self.obj, other.obj) <= 0
        def __ge__(self, other):
            return mycmp(self.obj, other.obj) >= 0
        def __ne__(self, other):
            return mycmp(self.obj, other.obj) != 0
    return K
当需要将cmp转化为key时,只需要:
代码如下:
>>> sorted([5, 2, 4, 1, 3], key=cmp_to_key(reverse_numeric))
[5, 4, 3, 2, 1]

从python2.7,cmp_to_key()函数被增加到了functools模块中。


8)其他注意事项
       * 对需要进行区域相关的排序时,可以使用locale.strxfrm()作为key函数,或者使用local.strcoll()作为cmp函数。
       * reverse参数任然保持了排序的稳定性,有趣的时,同样的效果可以使用reversed()函数两次来实现:
代码如下:
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> assert sorted(data, reverse=True) == list(reversed(sorted(reversed(data))))
       * 其实排序在内部是调用元素的__cmp__来进行的,所以我们可以为元素类型增加__cmp__方法使得元素可比较,例如:
代码如下:
>>> Student.__lt__ = lambda self, other: self.age < other.age
>>> sorted(student_objects)
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]


       key函数不仅可以访问需要排序元素的内部数据,还可以访问外部的资源,例如,如果学生的成绩是存储在dictionary中的,则可以使用此dictionary来对学生名字的list排序,如下:
代码如下:
>>> students = ['dave', 'john', 'jane']
>>> newgrades = {'john': 'F', 'jane':'A', 'dave': 'C'}
>>> sorted(students, key=newgrades.__getitem__)
['jane', 'dave', 'john']

 

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/350948.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

电脑内存占用莫名很高_CPU占用高,电脑莫名卡顿?万能的重启拯救不了就用这3招,妥了!...

大家还记得windows 10 1903推送时发生的大翻车事件吗&#xff1f;那次的更新主要是修复早期版本的Visual Basic 6、VBA和VBScript无反应、远端桌面出现当机黑屏幕等问题&#xff0c;但win10的更新总是“捡了芝麻&#xff0c;丢了西瓜”&#xff0c;解决早期问题而又出现新的问题…

5. 多线程程序如何让 IO 和“计算”相互重叠,降低 latency?

基本思路是&#xff0c;把 IO 操作&#xff08;通常是写操作&#xff09;通过 BlockingQueue 交给别的线程去做&#xff0c;自己不必等待。 例1: logging 在多线程服务器程序中&#xff0c;日志 (logging) 至关重要&#xff0c;本例仅考虑写 log file 的情况&#xff0c;不考…

tomcat web应用_具有可执行Tomcat的独立Web应用程序

tomcat web应用在部署应用程序时&#xff0c;简单性是最大的优势。 您将了解到&#xff0c;尤其是在项目发展且需要在环境中进行某些更改时。 将您的整个应用程序打包到一个独立且自足的JAR中似乎是个好主意&#xff0c;特别是与在目标环境中安装和升级Tomcat相比。 过去&#…

anaconda在ubuntu中添加环境变量

在ubuntu上安装好anaconda后&#xff0c;如果输入conda命令报错&#xff0c;很有可能需要以下修改注册表&#xff08;相当于windows中将路径添加到系统环境变量&#xff09; ~ /anaconda3/bin为.Sh所在home目录路径 在终端输入&#xff1a;sudo gedit ~/.bashrc 打开注册表后…

webpackjsonp 还原_具有催化CO2还原性能的非贵金属配合物的配体设计

Non-noble metal-based molecular complexes for CO2 reduction: From the ligand design perspectiveDong-Cheng Liu, Di-Chang Zhong, Tong-Bu LuEneryChem, 2, 100034 (2020).DOI: https://doi.org/10.1016/j.enchem.2020.100034全文链接https://www.sciencedirect.com/jour…

【数据库系统概论】第3章-关系数据库标准语言SQL(1)

文章目录 3.1 SQL概述3.2 学生-课程数据库3.3 数据定义3.3.1 数据库定义3.3.2 模式的定义3.3.3 基本表的定义3.3.4 索引的建立与删除3.3.5 数据字典 3.1 SQL概述 动词 分类 三级模式 3.2 学生-课程数据库 3.3 数据定义 3.3.1 数据库定义 创建数据库 tips&#xff1a;[ ]表…

适用于Java开发人员的Elasticsearch教程

课程大纲 Elasticsearch是基于Lucene的搜索引擎。 它提供了具有HTTP Web界面和无模式JSON文档的分布式多租户全文搜索引擎。 Elasticsearch是用Java开发的&#xff0c;并根据Apache许可的条款作为开源发布。 Elasticsearch是最受欢迎的企业搜索引擎&#xff0c;紧随其后的也是基…

shell实战之tomcat看门狗

1、脚本简介 tomcat看门狗&#xff0c;在tomcat进程异常退出时会自动拉起tomcat进程并记录tomcat运行的日志。 1 函数说明&#xff1a; 2 log_info&#xff1a;打印日志的函数&#xff0c;入参为需要在日志中打印的msg 3 start_tom&#xff1a;启动tomcat的函数…

tensorflow tf.train.batch()

tf.train.batch([example, label],batch_sizebatch_size, capacitycapacity) [example, label]表示样本和样本标签&#xff0c;这个可以是一个样本和一个样本标签&#xff0c;batch_size是返回的一个batch样本集的样本个数。capacity是队列中的容量。这主要是按顺序组合成一个b…

苹果6s上市时间_iPhone7的A10处理器还能战多长时间?2-3年不成问题!

iPhone 7采用A10 Fusion处理器&#xff0c;简称A10处理器&#xff0c;在2018年依然是处于高端处理器&#xff0c;再加上苹果自己的系统优化和资源调度&#xff0c;流畅度甚至超过其他安卓835机子。16年上市的iPhone7的A10还能再战多长时间&#xff1f;小编今天来分析一下。A10处…

tf.summary.FileWriter

ummary_waiter tf.summary.FileWriter("log",tf.get_default_graph()) log是事件文件所在的目录&#xff0c;这里是工程目录下的log目录。第二个参数是事件文件要记录的图&#xff0c;也就是tensorflow默认的图。

83998 连接服务器出错_服务端 TCP 连接的 TIME_WAIT 问题分析与解决

民工哥技术之路 写在开头&#xff0c;大概 4 年前&#xff0c;听到运维同学提到 TIME_WAIT 状态的 TCP 连接过多的问题&#xff0c;但是当时没有去细琢磨&#xff1b;最近又听人说起&#xff0c;是一个新手进行压测过程中&#xff0c;遇到的问题&#xff0c;因此&#xff0c;花…

SqlServer 时间格式化

select GETDATE() as 当前日期, DateName(year,GetDate()) as 年,DateName(month,GetDate()) as 月,DateName(day,GetDate()) as 日,DateName(dw,GetDate()) as 星期,DateName(week,GetDate()) as 周数,DateName(hour,GetDate()) as 时,DateName(minute,GetDate()) as 分,DateN…

[EBOOK]十大Java性能问题

有兴趣了解更多吗&#xff1f; 然后&#xff0c;您应该在此处下载相关的电子书。 Java中的大多数性能问题都可以归因于一些根本原因。 当然&#xff0c;偶尔会有一些奇怪的极端情况突然出现&#xff0c;并在应用程序中造成了严重破坏&#xff0c;但是在大多数情况下&#xff0…

请上传sku预览图后重新操作_拼多多商家版APP新增商品操作步骤

① 点击右下角“添加商品”按钮&#xff0c;进入创建商品页面&#xff1b;② 快速创建商品&#xff1a;目前手机版支持快速上传商品啦&#xff1a;仅通过上传商品标题、商品轮播图、商品分类、价格和库存&#xff0c;点击创建按钮&#xff0c;即可快速上传您的第一件店…

消息队列概述[幻灯片]

昨天我发表了一个演讲&#xff0c;涉及使用消息队列的所有方面。 我以前曾写过“您可能不需要消息队列” –现在的结论有些细微差别&#xff0c;但我仍然坚持简单性的观点。 演讲探讨了使用消息队列的各种好处和用例&#xff0c;并讨论了典型“消息队列代理”体系结构的替代方…

tf.reshape()

_image tf.reshape(x, [-1,28, 28, 1]) # -1表示任意数量的样本数,大小为28x28深度为一的张量 # 可以忽略(其实是用深度为28的,28x1的张量,来表示28x28深度为1的张量)

面向对象进阶-反射(二)重要知识点

# 面向对象的进阶# 其他常用模块# 作业 考试题# 网络编程 2天# ftp作业# class A:pass# class B(A):pass# a A()# print(isinstance(a,A))返回true&#xff0c;判断a是不是A的对象# print(issubclass(B,A))返回true&#xff0c;判断B是不是A的子类# print(issubclass(A,B))》…

异步过程的自动化测试

自从我开发了具有异步行为的服务器端应用程序以来已经有一段时间了&#xff0c;该行为还不是事件驱动的系统。 异步行为始终是设计和测试中一个有趣的挑战。 通常&#xff0c;异步行为不应该很难进行单元测试-毕竟&#xff0c;动作的行为不一定必须在时间上进行耦合&#xff08…

iphone以旧换新活动_iPhone第3轮降价背后:销售下滑库克甩锅给中国,国产手机崛起分食蛋糕...

排版 | 王科编辑 | 梁夜作者 | 吴晓宇来源 | 财经天下周刊(ID&#xff1a;cjtxzk)曾经吃掉手机行业9成利润的巨无霸公司苹果&#xff0c;不得不“自降身价”。3月5日之后&#xff0c;苏宁易购、京东、拼多多等多家电商平台纷纷宣布&#xff0c;再次对旗舰级iPhone XS系列产品降…