【Python3】Python3中的排序

这篇文章总结了 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

posted @ 2020-08-04 11:31  Flix  阅读(1077)  评论(0编辑  收藏  举报