排序是非常常见的一个场景,相比于Python2,Python3中的排序有不少优化,今天谈一谈Python3中常见排序场景~~更多细节可参考Ref中的Python官方文档链接(虽然里面也没有多少内容,不过很权威啊)
1. 基本排序
基本排序,有两种方式:sorted(list)和list.sort,前者sorted为一个函数,返回一个sorted的新list,后者为list的一个内建方法,在原list的基础上进行排序
2. 使用关键字key='...'
问题:想按照每个元素第三个值进行从小到大的排序,数据结构如下
student_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10) ]
方法:
sorted(student_tuples, key=lambda item: item[2])
解析:sorted函数执行时,遍历student_tuples中的每个元素,这里通过取出每个元素的第三个元素作为返回值用于排序,这里lambda函数的功能相当于:
def func(item):
return item[2]
对于简单些的数据结构,可以使用lambda函数,如若遇到更复杂情形,则建议自定义函数,使用自定义函数方式如下:
sorted(student_tuples, key=func)
*注意,自定义函数传给sorted函数key关键字时,无需为自定义函数提供参数,sorted函数遍历元素时,自动将参数传递给函数,用于判断排序
3.一个复杂排序规则的实现
问题:一个字符串排序,排序规则:小写
实现:
sorted(s, key=lambda x: (x.isdigit(),x.isdigit() and int(x) % 2 == 0,x.isupper(),x)
解析:
(1).x.isdigit()的作用是把数字放在后边(True),字母放在前面(False).
(2).x.isdigit() and int(x) % 2 == 0的作用是保证数字中奇数在前(False),偶数在后(True)。
(3).x.isupper()的作用是在前面基础上,保证字母小写(False)在前大写在后(True).
(4). 最后的x表示在前面基础上,对所有类别数字或字母排序。
(5). False=0,True=1,因此当一个元素被判断为False时,将会按照由小到大排在前面,同时元组内(e1, e2, e3)的优先级排列为: e1 > e2 > e3,如同excel中的主排序和次排序类似
4. 简化功能,使用operator模块
两个数据结构示例:
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_tuples = [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10) ]
排序方案:
from operator import itemgetter, attrgetter
sorted(student_objects, key=attrgetter('age'))
sorted(student_tuples, key=itemgetter(2))
针对上述两个数据结构的排序将会更快速(未测试,参考官方文档),同时由于operator是python内建模块,用起来应该还是比lambda匿名函数或自定义函数方便一些些的~
重要的事情再强调一下,当为key关键字提供一个元组时,会按照元组内的元素顺序进行优先级顺序排序,参见下例:
sorted(student_tuples, key=itemgetter(1,2))
output: [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
5. 升序,降序
这一块比较简单,只需为reverse关键字提供True或False即可,不提供时则默认为False(升序)
参考资料:
Ref1:https://docs.python.org/3.6/howto/sorting.html#sortinghowto
微信公众号:生信解码
领取专属 10元无门槛券
私享最新 技术干货