之前学习第九章的排序小结的时候,对sort()排序方法不理解,因为括号里面带了自定义的比较函数。
后来查手册,才发现sort()里面本来就带了这样的参数。能够自定义比较方法,确实很灵活。
不仅如此,在网上查到一个博客,作者不单停留在这表面,还查究了sort()的排序算法,确实有意思。
全文抄录如下:
http://blog.donews.com/maverick/archive/2006/07/09/951101.aspx
学习笔记:Python的排序
Python语言内置了sort方法,可以很方便地对某个List进行排序:
L = [6, 5, 1, 3, 4, 2]
L.sort()
print L
---------- Run Python Program ----------
[1, 2, 3, 4, 5, 6]
某些时候,我们希望按照自己定义的排序规则来排序(例如,按关键词的权重排序,按人的年龄排序,等等)。在Java语言中,我们可以自定义Comparator来实现,Python中也提供了类似的办法。
若List中每个元素都是2-tuple,tuple中第一个元素为String类型的keyword,第二个元素为该字符串对应的权重(int类型),希望按照权重排序(从高到低),则可以这样:
def my_cmp(E1, E2):
    return -cmp(E1[1], E2[1])    #compare weight of each 2-tuple
                    #return the negative result of built-in cmp function
                    #thus we get the descend order
L = [('a', 0), ('b', 1), ('c', 2), ('d', 3)]
L.sort(my_cmp)
print L
---------- Run Python Program ----------
[('d', 3), ('c', 2), ('b', 1), ('a', 0)]
正因为可以自定义cmp方法,我们不妨探究一下,built-in的sort方法,到底是采用的哪一种排序算法:
from random import shuffle
def my_cmp(E1, E2):
    print 'E1:', E1, 'E2:', E2
    return cmp(E1, E2)
L = range(0, 10)
shuffle(L)
print L
L.sort(my_cmp)
---------- Run Python Program ----------
[5, 3, 7, 6, 2, 8, 9, 4, 1, 0]
E1: 3 E2: 5
E1: 7 E2: 3
E1: 7 E2: 5
E1: 6 E2: 5
E1: 6 E2: 7
E1: 2 E2: 6
E1: 2 E2: 5
E1: 2 E2: 3
E1: 8 E2: 5
E1: 8 E2: 7
E1: 9 E2: 6
E1: 9 E2: 8
E1: 4 E2: 6
E1: 4 E2: 3
E1: 4 E2: 5
E1: 1 E2: 6
E1: 1 E2: 4
E1: 1 E2: 3
E1: 1 E2: 2
E1: 0 E2: 5
E1: 0 E2: 3
E1: 0 E2: 2
E1: 0 E2: 1
可以看到,每次调用my_cmp,E1依次是List中的第2、3、4……直到最后一个元素,可以肯定sort不是采用的分治法(devide-and-conqure)
看 前三次调用,可以发现sort采用的是典型的插入排序——也就是说,将新元素插入已排序部分的合适位置,查找位置时采用的似乎是从后向前线形探察的办法。 从元素6开始,新元素不再直接与已排序部分的最后元素比较,而是先与中间值比较,采用二分检索探察合适位置,这样,可以把时间代价从n缩小到 log(n)。
至此,我们可以认为,built-in的sort方法,采用的是“二分法插入排序”(binary insertion)的算法。
为了检测这个结论,可以输入一个已排序的数组,看看结果。
L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
L.sort(my_cmp)
---------- Run Python Program ----------
E1: 1 E2: 0
E1: 2 E2: 1
E1: 3 E2: 2
E1: 4 E2: 3
E1: 5 E2: 4
E1: 6 E2: 5
E1: 7 E2: 6
E1: 8 E2: 7
E1: 9 E2: 8
E1: 10 E2: 9
结果发现,比较的次数非常少,插入每个元素的时候,只会与它之前紧邻的元素比较,而不是二分检索。这真是个有意思的现象。
改一改程序
L = [0, 1, 2, 3, 4, 5, 6, 8, 7, 9, 10]
L.sort(my_cmp)
---------- Run Python Program ----------
E1: 1 E2: 0
E1: 2 E2: 1
E1: 3 E2: 2
E1: 4 E2: 3
E1: 5 E2: 4
E1: 6 E2: 5
E1: 8 E2: 6
E1: 7 E2: 8
E1: 7 E2: 4
E1: 7 E2: 6
E1: 7 E2: 8
E1: 9 E2: 4
E1: 9 E2: 7
E1: 9 E2: 8
E1: 10 E2: 5
E1: 10 E2: 8
E1: 10 E2: 9
可以看到,在数字8以前,List中的元素都是有序的,于是sort算法也只比较欲插入元素和已排序序列的最后一个元素;一旦发现输入序列不是自然有序之后,就采用二分插入排序算法。
这样的混合排序算法,相对单纯的插入排序,保证了最好条件下时间代价最低,也减小了一般情况下的时间代价。
p.s.
写完之后查阅Python的文档,发现sort采用的是混合(hybrid)排序,规模小的时候采用binary insertion,规模大的时候采用samplesort

Python的sort()相关推荐

  1. python:sort,sorted,argsort,lexsort

    Python list内置sort()方法用来排序,也可以用python内置的全局sorted()方法来对可迭代的序列排序生成新的序列 目录 1.使用sort排序 2.使用sorted()排序 key ...

  2. Python 排序 -- sort()、sorted()

    Python 排序 – sort().sorted() 1. 列表排序:sort() 函数原型: 直接对列表本身进行排序,不会返回新的列表 list.sort(cmp=None, key=None, ...

  3. python数组排序sort_详解python中sort排序使用

    1.前言 昨天一学妹问我一个关于python的问题,当时在外忙碌,没时间细看.今天看一下,咋一看我还真的不知道这个问题,bookinfo.sort(reverse=True ,key=lambda x ...

  4. python中sort和sorted区别_Python中的 sort 和 sorted的用法与区别

    今天在做一道题时,因为忘了Python中sort和sorted的用法与区别导致程序一直报错,找了好久才知道是使用方法错误的问题!现在就大致的归纳一下sort和sorted的用法与区别 1. sort: ...

  5. python不用sort排序_Python排序之sortamp;sorted

    1 首先,Python中sort与sorted的区别: python中列表的内置函数sort()可以对列表中的元素进行排序,sort()函数是内置函数,会改变当前对象: 而全局性的sorted()函数 ...

  6. Python中sort和sorted函数代码解析

    Python中sort和sorted函数代码解析 本文研究的主要是Python中sort和sorted函数的相关内容,具体如下. 一.sort函数 sort函数是序列的内部函数 函数原型: L.sor ...

  7. python中sort什么意思,python中sort是什么意思

    Python里的sort语句 >>> x = [[1,4],[5,2]] >>> x [[1, 4], [5, 2]] >>> x.sort() ...

  8. python列表sort倒序输出_Python 列表sort()添加key和reverse参数操作方法|python基础教程|python入门|python教程...

    https://www.xin3721.com/eschool/pythonxin3721/ 本文是关于Python 列表sort()添加key和reverse参数操作方法介绍,之前python so ...

  9. python中sort函数源代码_Python中sort和sorted函数代码解析

    Python中sort和sorted函数代码解析 本文研究的主要是Python中sort和sorted函数的相关内容,具体如下. 一.sort函数 sort函数是序列的内部函数 函数原型: L.sor ...

最新文章

  1. R语言使用caret包中的createMultiFolds函数对机器学习数据集进行交叉验证抽样、返回的样本列表长度为k×times个、times为组内抽样次数
  2. Design Pattern - Builder(C#)
  3. 区块链BaaS云服务(32)同盾科技 IASC平台
  4. windows编程一日一练(2)
  5. android 接口定义常量,Android开发笔记(5):常量的合理使用
  6. 深度好文 | 战“疫”上云正当时:打开云计算的正确姿势
  7. ReactNative开发工具有这一篇足矣
  8. 部署虚拟环境安装Linux系统(Linux就该这么学)笔记
  9. FreeCodeCamp Caesars密码项目的演练
  10. leetcode—19.二叉树遍历相关题目leetcode总结
  11. TYVJ P1022 进制转换 Label:坑
  12. python 读取json与xml格式化等处理
  13. 神州数码DCN交换机SNMP配置命令
  14. thrift 编译报错 undefined reference
  15. jersey tomcat MySQL_基于jersey和Apache Tomcat构建Restful Web服务(一)
  16. 【数据处理与分析】matplotlib快速入门
  17. PuTTY 下载安装教程
  18. 监控文件变化 (Python—看门狗)
  19. 【踩坑记录】为VMware虚拟机引用主机代理
  20. Linux命令·ln

热门文章

  1. Shell教程(三):数组/Arrays、基本运算符
  2. 2019年10个最受欢迎的JavaScript动画库!
  3. OPNsense 18.7.X汉化包发布!
  4. git生成sshkey
  5. 深智云 让企业在物联网时代实现数据价值
  6. 从JVM指令层面看try-catch-finally返回值问题
  7. Oracle提议将G1作为Java 9的默认垃圾收集器
  8. php stock 资料地址
  9. (C#)链接本地数据SDF。
  10. 第一章:linux管理文件和目录