这篇文章总结了 Python3 中的排序方法。
sort 和 sorted 的区别
sort
只能对列表进行排序,使用方式为list.sort()
,返回值为空。sorted
对所有可迭代对象(例如元组、列表、字典等)进行排序,返回排好序的对象。
list.sort() | sorted() |
---|---|
sort(*, key=None, reverse=False) | sorted(iterable, *, key=None, reverse=False)) |
列表可以使用 | 所有可迭代对象均可使用 |
原地排序,无返回值 | 不改变原对象,返回一个排序好的对象 |
默认根据 key 的大小从小到大排序(升序排序)。
列表排序
列表可以使用list.sort()
或者sorted(list)
来进行排序。
list.sort()的语法为
sort(*, key=None, reverse=False)
其中,key 表示使用哪一个元素进行排序;reverse 表示是否反向排序,reverse=True 表示反向排序。注意在 Python2 中可以使用比较参数 cmp,而 Python3 将比较参数 cmp 删除。
假设,列表 a 如下:
a = [1, 3, 5, 2, 4, 6]
则可以使用 list.sort 和 sorted 两种方法对 a 从大到小排序
a = [1,3,5,2,4,6]
a.sort() # [1, 2, 3, 4, 5, 6]
sorted(a) # [1, 2, 3, 4, 5, 6]
指定reverse=True
便可以从小到大排序
a = [1,3,5,2,4,6]
a.sort(reverse=True) # [6, 5, 4, 3, 2, 1]
sorted(a, reverse=True) # [6, 5, 4, 3, 2, 1]
假设 a 是二维的
a = [[1, 2, 8], [3, 9, 6], [0, 5, 7]]
我们想根据数组的每一个一维数组的第一个元素(第一列)来排序,则可以使用 key 来指定要排序的元素
sorted(a, key=lambda x:x[0]) # [[0, 5, 7], [1, 2, 8], [3, 9, 6]]
可以看到,key 是一个 lambda 函数,该函数返回一个元素,数组根据该元素进行排序。
同样地,如果想根据每一个一维数组的第二个元素(第二列)来排序,则
sorted(a, key=lambda x:x[1]) # [[1, 2, 8], [0, 5, 7], [3, 9, 6]]
元组不能使用 tuple.sort()
进行排序,可以使用 sorted()
来排序,其他和列表排序基本一致,这里不再赘述。
字典排序
字典可以使用 sorted() 来进行排序,需要注意的是,sorted 返回的不是排序后的字典,而是排序后字典的 key。
假设字典 d 如下:
d = {'a':10, 'b':30, 'c':20}
按 key 排序
按 key 正序(从小到大)排序
d = {'a':10, 'b':30, 'c':20}
sorted(d) # ['a', 'b', 'c']
逆序排序只需指定 reverse=True
d = {'a':10, 'b':30, 'c':20}
sorted(d, reverse=True) # ['c', 'b', 'a']
如果我们想得到排序后的整个字典,而不仅仅是排序后的 key,则可以使用如下方式
{k:d[k] for k in sorted(d, reverse=True)} # {'c': 20, 'b': 30, 'a': 10}
按 value 排序
在 sorted 函数中,将参数 key 指定为字典的 value 来就可以根据 value 进行排序。例如
sorted(d, key=lambda k:d[k]) # ['a', 'c', 'b']
{k:d[k] for k in sorted(d, key=lambda k:d[k])} # {'a': 10, 'c': 20, 'b': 30}
假设,字典的 value 是列表类型的
d = {'a':[1,2,8], 'b':[3,9,6], 'c':[0,5,7]}
假如我们想根据数组的第一维进行排序,则
d = {'a':[1,2,8], 'b':[3,9,6], 'c':[0,5,7]}
sorted(d, key=lambda x:d[x][0]) # ['c', 'a', 'b']
{k:d[k] for k in sorted(d, key=lambda x:d[x][0])} # {'c': [0, 5, 7], 'a': [1, 2, 8], 'b': [3, 9, 6]}
同样地,如果我们想根据数组的第二维进行排序,则
d = {'a':[1,2,8], 'b':[3,9,6], 'c':[0,5,7]}
sorted(d, key=lambda x:d[x][0]) # ['a', 'c', 'b']
{k:d[k] for k in sorted(d, key=lambda x:d[x][1])} # {'a': [1, 2, 8], 'c': [0, 5, 7], 'b': [3, 9, 6]}
自定义对象的排序
假设我们有一个学生类 Student
class Student:
def __init__(self, name, age, score):
self.name = name
self.age = age
self.score = score
def show(self):
print(f"[{self.name}, {self.age}, {self.score}]")
我们构建一个学生列表
students = [Student('a', 20, 90), Student('b', 22, 85), Student('c', 21, 95)]
如果我们想按照学生的年龄 age 排序,则在 sorted 函数中指定参数 key = student.age 即可。
students = sorted(students, key=lambda x:x.age) # 注意要将排好序的对象重新赋值给 students
for student in students:
student.show()
输出:
[a, 20, 90]
[c, 21, 95]
[b, 22, 85]
如果想降序排序,设置 reverse=True 即可
students = sorted(students, key=lambda x:x.age, reverse=True)
for student in students:
student.show()
输出:
[b, 22, 85]
[c, 21, 95]
[a, 20, 90]
同样地,如果想按照学生的分数 score 进行排序,则指定 sorted 函数中指定参数 key = student.score 即可
students = sorted(students, key=lambda x:x.score)
for student in students:
student.show()
输出:
[b, 22, 85]
[a, 20, 90]
[c, 21, 95]
参考
1、https://www.polarxiong.com/archives/Python-使用lambda应对各种复杂情况的排序-包括list嵌套dict.html
2、https://www.runoob.com/python/python-func-sorted.html
3、https://docs.python.org/3/howto/sorting.html
4、https://docs.python.org/3/library/stdtypes.html#list.sort
5、https://docs.python.org/3/library/functions.html#sorted