排序sort&sorted
一、说明
Python 列表有一个内置的 list.sort()
方法可以直接修改列表。还有一个 sorted()
内置函数,它会从一个可迭代对象构建一个新的排序列表。
list.sort() 在原列表中进行排序,sorted()对原可迭代对象进行排序,但不改变原可迭代对象,生成一个新的副本。
list.sort( key=None, reverse=False)
sorted(iterable, key=None, reverse=False)
二、关键函数
list.sort()
和 sorted()
都有一个 key 形参来指定在进行比较之前要在每个列表元素上进行调用的函数。
list_1 = sorted("This is a test string from python".split(), key=str.lower) # 不区分大小写进行排序 print(list_1)
key 形参的值应该是一个函数,它接受一个参数并并返回一个用于排序的键。这种技巧速度很快,因为对于每个输入记录只会调用一次 key 函数。
list_1 = "This is a test string from python".split() list_2 = sorted(list_1, key=lambda x: x.lower()) print(list_2)
使用对象的一些索引作为键对复杂对象进行排序
student_tuples = [ ('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10) ] list_1 = sorted(student_tuples, key=lambda x: x[2]) # 根据每个元组中的第3个元素进行排序 print(list_1)
三、Operator 模块函数
上面显示的键函数模式非常常见,因此 Python 提供了便利功能,使访问器功能更容易,更快捷。 operator
模块有 itemgetter()
、 attrgetter()
和 methodcaller()
函数。
from operator import itemgetter, attrgetter student_tuples = [ ('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10), ] student_1 = sorted(student_tuples, key=itemgetter(2)) print(student_1)
四、升序和降序
接受布尔值的 reverse 参数。这用于标记降序排序。
默认reverse = False。正序排列。
五、 排序稳定性与排序复杂度
排序保证是稳定的。 这意味着当多个记录具有相同的键值时,将保留其原始顺序。
from operator import itemgetter, attrgetter list_1 = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)] list_2 = [('red', 2), ('blue', 2), ('red', 1), ('blue', 1)] list_3 = sorted(list_1, key=itemgetter(0), reverse=False) list_4 = sorted(list_2, key=itemgetter(0), reverse=False) # 对第一个元素进行排序,第二个元素的顺序和原可迭代对象保持一致 print(list_3) print(list_4)
也可以按照第一个元素升序,第二个元素降序
思路先按第二个元素降序生成第一个副本,再按一个元素升序生成第二个副本。
from operator import itemgetter, attrgetter list_1 = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)] list_2 = sorted(list_1, key=itemgetter(1), reverse=True) list_3 = sorted(list_2, key=itemgetter(0), reverse=False) print(list_3)
注意:如果按第一个元素升序,第二个元素降序,先写二个元素降序,在写第一个元素升序