Python中的排序
阅读官方文档 how-to-sort 记录笔记
基本排序
利用sorted函数可以直接对可迭代对象(Iterable,可利用for语句来访问)进行排序,可返回一个经过排序的列表,而不改变原始数据:
>>> sorted([5, 4, 3, 2, 1])
[1, 2, 3, 4, 5]
>>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'})
[1, 2, 3, 4, 5]
也可以使用list.sort()方法,不过这个方法只对list有用,且会改变原始数据
>>> a = [5, 4, 3, 2, 1]
>>> a.sort()
>>>a
[1, 2, 3, 4, 5]
排序中的key函数
list.sort() 和sorted() 都有一个key 参数,先作用在列表中的每一个元素上,再进行排序比如:
>>>sorted("This is a test string".split(), key = str.lower)
['a', 'is', 'string', 'test', 'This']
将数据中的索引作为排序依据:
>>> 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)]
利用Operator中的函数进行排序
operator模块中的itemgetter() 、attrgetter()、 和amethodcaller() 方法能够为排序提供更方便的key 参数接口:
>>> 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)]
一些排序技巧
- 先对grade排序,若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)]
- 按照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)]