Python 集合的遍历,推导及 filter/map/reduce 操作 中讲了对集合的 filter, map 和 reduce 操作,那还有 sort 排序呢?像 Java 一样,Python  也提供了 sort() 和 sorted() 方法。

sort() 是 list 的实例方法, sorted() 是一个内置函数。Python 中也是只有 list 才有顺序。

list.sort() 方法

查看 Python 3 中的 list.sort() 方法(help(list.sort))

Help on method_descriptor:

sort(self, /, *, key=None, reverse=False)

Stable sort *IN PLACE*.

Python 的 list.sort() 方法和 Java List.sort() 方法一样的,都是 IN PLACE 排序,没有返回值。实际看下各种排序场景

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

>>>s1=[2,1,5,3,4]

>>>s1.sort()

>>>s1

[1,2,3,4,5]

>>>s.sort(reverse=True)

>>>s

[5,4,3,2,1]

>>>s2=[('c',2),('a',1),('b',5),('e',3),('d',4)]

>>>s2.sort()

>>>s2

[('a',1),('b',5),('c',2),('d',4),('e',3)]

>>>s2.sort(key=lambdaitem:item[1])

>>>s2

[('a',1),('c',2),('e',3),('d',4),('b',5)]

>>>s2.sort(key=lambdaitem:item[1],reverse=True)

>>>s2

[('b',5),('d',4),('e',3),('c',2),('a',1)]

list.sort() 能直接对可比较比象进行排序,也就是两个对象间能用 < 号相比较,映射到函数就是 __lt__。数字字符串都能比,从前面看到两个 tuple 也可以比较,

1

2

>>>('c',2)

False

如果两个元素之间不能进行比较的话,可以指定 key 参数来取出相关值进行比较,如上面的 key=lambda item: item[1], 取 tuple 的第二个元素进行

再来看自定义对象的比较

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

>>>classUser:

...def__init__(self,name,email):

...self.name=name

...self.email=email

...

...defget_name(self):

...returnself.name

...

...def__repr__(self):

...returnf'User: name={self.name}, email={self.email}'

...

...

...

>>>users=[User('cc','hh@g.com'),User('aa','ii@g.com'),User('bb','ee@g.com')]

>>>users.sort()

Traceback(mostrecentcalllast):

File"",line1,in

users.sort()

TypeError:'

>>>users.sort(key=lambdauser:user.get_name())

>>>users

[User:name=aa,email=ii@g.com,User:name=bb,email=ee@g.com,User:name=cc,email=hh@g.com]

>>>users.sort(reverse=True)

Traceback(mostrecentcalllast):

File"",line1,in

users.sort(reverse=True)

TypeError:'

users.sort() 不管 reverse 是 False 还是 True,始终是试图用 < 去比较两个对象。由于 User 没有定义 __lt__ 方法,所以不能直接对 User 进行排序,而必须指定 key=lambda user: user.get_name() 依照 get_name() 的返回值进行排序。

如何让对象是可比较的呢,或者直截说验证一下 Python 是否是调用了 __lt__ 方法来比较函数。接下来动态的给 User 类添加一个  __lt__ 方法,然后变 users.sort() 从不可能到可能

1

2

3

4

5

6

7

8

9

10

>>>deflittle(self,that):

...print(f'compare {self}, {that}')

...returnself.email

...

>>>setattr(User,'__lt__',little)

>>>users.sort()

compareUser:name=cc,email=hh@g.com,User:name=bb,email=ee@g.com

compareUser:name=aa,email=ii@g.com,User:name=cc,email=hh@g.com

>>>users

[User:name=bb,email=ee@g.com,User:name=cc,email=hh@g.com,User:name=aa,email=ii@g.com]

这时候发现不用指定 key 对 users 也可以排序了,比较时调用了 __lt__ 方法。

前面提到过只能对 list 进行排序,也就是只有 list 才有 sort() 方法,这也不难理解,set, tuple, dict 是不存在顺序观念的。但有意思的是,在对 set, tuple 转换成 list 后便自动立马有了顺序。

1

2

3

4

5

6

>>>s={2,1,3}

>>>list(s)

[1,2,3]

>>>t=(2,1,3,2)

>>>list(t)

[2,1,3,2]

这也为接下来要看到的 sorted() 函数作了一个铺垫。前面只有 list 才有 sort() 方法,然而内置的 sorted() 函数除了对 list 进行排序,对 set 和 tuple 也能排序,效果上相当于转换为 list,再对 list 排序,所以最终 sorted() 后得到的都是一个 list。

内置的 sorted() 函数

同样,用 help(sorted) 看下它的原型

Help on built-in function sorted in module builtins:

sorted(iterable, /, *, key=None, reverse=False)

Return a new list containing all items from the iterable in ascending order.

A custom key function can be supplied to customize the sort order, and the

reverse flag can be set to request the result in descending order.

之于 list.sort() 方法,我们只需记住 sorted() 的几个不同之处

它是一个内置函数,所以第一个参数传入待排序的集合

待排序的集合不受限于 list, 它是 iterable, 根据鸭子类型的规则,只要该类实现了 __iter__() 方法就是 iterable。具体说来就是能使用 for..in.. 进行遍历的都能排序,像 set, tuple, 或 dict.items() 等

排序不再是 IN PLACE, 也就是它的排序不改变原集合,而是生成一个新的 list 并返回

其他的排序行为与list.sort() 函数是一致的。

看下执行效果,对 list, tuple 和  set 进行排序

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

>>>s=[2,1,5,3,4]

>>>nums=[2,1,5,3,4]

>>>new_nums=sorted(nums)

>>>nums

[2,1,5,3,4]

>>>new_nums

[1,2,3,4,5]

>>>t=(2,1,5,3,4)

>>>t1=sorted(t)

>>>t

(2,1,5,3,4)

>>>t1

[1,2,3,4,5]

>>>type(t1)

>>>s={2,1,5,3,4}

>>>s1=sorted(s)

>>>s

{1,2,3,4,5}

>>>s1

[1,2,3,4,5]

>>>type(s1)

不用理会 Python 怎么显示 set 中的内容,因为 set 是不能用索引号访问的。无论是对 tuple 还是 set 排序后得到的结果都是 list,sorted() 对原集合是无副作用的。

对比一下 Java 的 sort()  与 sorted() 方法

先看一下 Java 的这两个方法, Java 的 Collections 的类提供了两个 sort 方法

1

2

3

4

5

6

7

publicstatic>voidsort(Listlist){

list.sort(null);

}

publicstaticvoidsort(Listlist,Comparator<?superT>c){

list.sort(c);

}

它们接受的参数是 List, 所以也是只针对 List 进行排序,也是 IN PLACE 的, 也是无返回值的。sorted() 出现在 Java 的 Stream

它得到的结果还是 Stream,因此它也是无副作用的,最后需要 collect(tolist()) 得到一个新的集合。

关于排序算法

Python 和 Java 对 List 进行排序的算法都是 Timsort, 摘录一下中文维基百科中的内容

Timsort 是一种混合稳定的排序算法,源自合并排序和插入排序,旨在较好地处理真实世界中各种各样的数据。它使用了 Peter Mcllroy 的"乐观排序和信息理论上复杂性"中的技术,参见 第四届年度ACM-SIAM离散算法研讨会论文集,第467-474页,1993年。 它由 Tim Peters 在2002年实现,并应用于 Python编程语言。该算法通过查找已经排好序的数据子序列,在此基础上对剩余部分更有效地排序。 该算法通过不断地将特定子序列(称为一个 run )与现有的 run 合并,直到满足某些条件为止来达成的更有效的排序。 从 2.3 版本起,Timsort 一直是 Python 的标准排序算法。 它还被 Java SE7Android platformGNU Octave,谷歌浏览器,Swift

python的内置函数列表排序_Python 列表的排序 - sort/sorted相关推荐

  1. python编程内置函数使用方法_python编程(4)--内置函数

    ​     函数,通常称为方法,是一种将自变量到因变量的映射(y = f(x)).在python里用def或者lambda去构造,语法如下. def f(x):      #x -- 输入 y = x ...

  2. python编程内置函数使用方法_Python内置函数 next的具体使用方法

    Python 3中的File对象不支持next()方法. Python 3有一个内置函数next(),它通过调用其next ()方法从迭代器中检索下一个项目. 如果给定了默认值,则在迭代器耗尽返回此默 ...

  3. python中内置函数的用法_python中str内置函数用法总结

    大家在使用python的过程中,应该在敲代码的时候经常遇到str内置函数,为了防止大家搞混,本文整理归纳了str内置函数.1字符串查找类:find.index:2.字符串判断类:islower.isa ...

  4. python给内置函数重命名_python – 以Pandas Groupby函数重命名列名

    1).我有一个以下示例数据集: >>> df ID Region count 0 100 Asia 2 1 101 Europe 3 2 102 US 1 3 103 Africa ...

  5. python内置函数及方法_python 内置函数 应用及方法

    一.主要内容: 1.内置函数 什么是内置函数? 就是python给你提供的. 拿来直接⽤的函数, 比如print., input等等. 截⽌ 到python版本3.6.2 python⼀共提供了68个 ...

  6. python常用内置函数总结-Python 常用内置函数

    Python 常用内置函数如下: 1. abs()函数返回数字的绝对值. print( abs(-45) )# 返回45print("abs(0.2):",abs(0.2))#返回 ...

  7. len是python的内置函数吗_len(x) 击败 x.len(),从内置函数看 Python 的设计思想(内有公号宣传,不喜勿进)...

    内置函数是 Python 的一大特色,用极简的语法实现很多常用的操作. 它们预先定义在内置命名空间中,开箱即用,所见即所得.Python 被公认是一种新手友好型的语言,这种说法能够成立,内置函数在其中 ...

  8. python的内置函数

    python的内置函数: 1.abs() 将负数取正 print(abs(-10)) 2.all() 全部为真结果为真 print(all([1,0])) 3.any() 有一个为真,结果为真 pri ...

  9. 什么是python的内置函数_什么是python内置函数

    python的内置函数截止到python版本3.6.2,现在python一共为我们提供了68个内置函数.它们就是python提供给你直接可以拿来使用的所有函数.那今天我们就一起来认识一下python的 ...

  10. Python模块内置函数

    一.任务描述   本实验任务主要完成对Python模块内置函数进行一些基本操作,通过完成本实验任务,要求学生熟练掌握Python模块内置函数,并对Python内置函数的基本操作进行整理并填写工作任务报 ...

最新文章

  1. python使用input函数时、必须添加提示文字-Python基础教程(4)使用input函数实现用户交互...
  2. nginx负载均衡的session共享问题的解决方法
  3. JUnit简介与初步使用
  4. 记录docker开发hadoop,解决bug Datanode denied communication with namenode because hostname cannot be
  5. 想基于K8s按需扩展应用程序,可从这几方面入手
  6. ssm使用全注解实现增删改查案例——IEmpService
  7. java quartz 2.2.3_java – Spring 3 Quartz 2错误
  8. 新版 chrome 将原生支持图片懒加载!
  9. 史上最迷你人脸数据集olivettifaces基于卷积神经网络模型+迁移学习构建人脸识别模型实战
  10. 【svn】SSL error: A TLS warning alert has been received的解决方法
  11. **JAVA实习周记(第一周):任何的浮躁都是阻碍**
  12. 站斧超级浏览器风控系统助力Lazada商家安全管理
  13. kafka集群搭建(三台服务器)
  14. 达芬奇密码--buuctf密码学
  15. 专转本-数学考试大纲
  16. park停车场项目实战
  17. 你是要搞敏捷吗?教你挑选试点团队的盖世绝招
  18. Mapbox使用详解
  19. java 一对多关系修改,java – EclipseLink以一对多关系生成重复条...
  20. vue 所见即所得_适用于Vue.js的轻量级所见即所得HTML编辑器

热门文章

  1. 外贸行业签合同以及付款的技巧
  2. 《Google资深工程师深度讲解Go语言》学习笔记
  3. 电路板电镀中4种特殊的电镀方法
  4. 如何打造城市专属的夜游灯光秀产品
  5. 【微信小程序】微信小程序使用表单的一些坑和注意事项
  6. mysql笔记(锁、事务、性能优化、压测结果)
  7. 【opencv-python】Sobel算子说明
  8. 06-[案例1]鼠标移出移入控制二维码的显示与隐藏
  9. 例题4-1 古老的密码(Ancient Cipher, NEERC 2004, UVa1339)
  10. 丁丁学数学(2-3)