Return a new sorted list from the items in iterable.
Has two optional arguments which must be specified as keyword arguments.
key specifies a function of one argument that is used to extract a comparison key from each list element: key=str.lower. The default value is None (compare the elements directly).
reverse is a boolean value. If set to True, then the list elements are sorted as if each comparison were reversed.
Use functools.cmp_to_key() to convert an old-style cmp function to a key function.
The built-in sorted() function is guaranteed to be stable. A sort is stable if it guarantees not to change the relative order of elements that compare equal — this is helpful for sorting in multiple passes (for example, sort by department, then by salary grade).
For sorting examples and a brief sorting tutorial, see Sorting HOW TO.
根据iterable中的项返回一个新排序的列表。
这里有两个可选参数,其必须指定为关键字参数。
内建sorted()函数可以保证稳定,如果它保证不改变元素的相对顺序,那么排序就是稳定的。相对顺序的比较恒等,对于多次传递下的排序很有用(例如:按部门排序,然后按工资等级排序)
实例摘自官方手册
# 简单排序 >>> sorted([5, 2, 3, 1, 4]) [1, 2, 3, 4, 5] # list.sort()方法,该方法仅对列表定义。 >>> a = [5, 2, 3, 1, 4] >>> a.sort() >>> a [1, 2, 3, 4, 5] # sorted()支持任何迭代形式 >>> sorted({ 1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'}) [1, 2, 3, 4, 5]
list.sort()和sorted()都有key参数,用来指定一个函数,并对每个列表元素对象调用该函数进行比较。
# 小写字符串比较,key=str.lower >>> 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]) # 依照年龄排序 [('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) # 依照年龄排序 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
上面展示的是很常见的key函数模式,因此Python提供了便捷的函数来使访问器函数更简单、更迅速,operator模块有itemgetter()、attrgetter()和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模块函数允许多层级排序,例如,先按等级排序,然后按年龄:
>>> >>> 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)]
list.sort()和sorted()都接受reverse参数(布尔值),这用于标识降序排序,例如:以反向年龄顺序获取学生数据:
>>> >>> 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)]
排序可以保证稳定性,这意味着如果多个记录具有相同的键,它们原来的顺序是受保护的。
>>> >>> 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)之前的。
这条神奇的属性可以让你在一系列的排序级内建立复杂排序,例如:以年级降序排列学生数据,然后升序排列年龄。因此先做年龄排序,然后再使用年级排序:
>>> >>> s = sorted(student_objects, key=attrgetter('age')) # 以第二个键排序 >>> sorted(s, key=attrgetter('grade'), reverse=True) # 现在以第一个键降序排序 [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
Python的多重排序使用了Timsort算法,感兴趣的同学可以自行查找资料。
>>> >>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)] >>> standard_way = sorted(data, key=itemgetter(0), reverse=True) >>> double_reversed = list(reversed(sorted(reversed(data), key=itemgetter(0)))) >>> assert standard_way == double_reversed >>> standard_way [('red', 1), ('red', 2), ('blue', 1), ('blue', 2)]
>>> >>> Student.__lt__ = lambda self, other: self.age < other.age >>> sorted(student_objects) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> >>> students = ['dave', 'john', 'jane'] >>> newgrades = { 'john': 'F', 'jane':'A', 'dave': 'C'} >>> sorted(students, key=newgrades.__getitem__) ['jane', 'dave', 'john']
operator
itemgetter()
attrgetter()
methodcaller()
locale.strxfrm()
locale.strcoll()
reversed()