【Python】列表或字典排序指南(官方文档翻译)

文章目录

  • 引言
  • 注意
  • 排序
    • 基本排序
    • Key 函数
    • 升序降序
    • 字典排序
    • Operator 模块函数(拓展知识,不必掌握)
    • 排序稳定性/复杂度(拓展知识,不必掌握)
  • 参考


引言

Python 列表有一个内置的 list.sort() 方法可以直接修改列表、进行排序。还有一个 sorted() 内置函数,它会从一个可迭代对象构建一个新的排序列表。在本文中,我们将探索使用 Python 对数据进行排序的各种技术。

注意

首先,我们需要明确的是,本文讲解的是 Python 列表的排序方法。而 Python 中的字典是无序的,所以字典本身不存在排序问题。但有时候我们需要对字典中的键值对排序,那么先转为列表或可迭代对象,然后再调用列表的排序方法就行了。

排序

基本排序

简单的升序排序非常容易:只需调用 sorted() 函数即可,它返回一个新的已排序列表。

>>> a = [5, 2, 3, 1, 4]
>>> a
[5, 2, 3, 1, 4]
>>> b = sorted(a)
>>> b
[1, 2, 3, 4, 5]

你也可以用 list.sort() 方法。它会直接修改原列表(并返回 None 以避免混淆),通常来说它不如 sorted() 方便——但如何你不需要原李彪,它会更有效率。

>>> a = [5, 2, 3, 1, 4]
>>> a.sort()
>>> a
[1, 2, 3, 4, 5]

另一个区别是 list.sort() 方法仅为列表定义,而 sorted() 函数接受任何可迭代对象输入(一般来说,可用 for 循环进行迭代的对象都是可迭代对象,如列表、字典、集合、字符串等等)。

>>> a = {5, 2, 3, 1, 4} # 定义一个集合类型的变量
>>> b = sorted(a)
>>> b
[1, 2, 3, 4, 5]
>>> a.soted() # .sort()是列表的排序方法,不支持其它数据类型, 所以会报错
Traceback (most recent call last):
  File "", line 1, in <module>
AttributeError: 'set' object has no attribute 'soted'

Key 函数

list.sort() 和 sorted() 都有一个 key 形参用来指定在进行比较前要在每个列表元素上调用的函数(或其它可调用对象)。

key 形参的值应该是个函数(或其他可调用对象),它接受一个参数并返回一个用于排序的键。这种机制速度很快,因为对于每个输入记录只会调用一次键函数。

一种常见的模式是用一些对象的索引作为键对复杂对象进行排序。例如:

>>> stds = [ # 姓名,成绩,年龄
...     ('john', 'A', 15),
...     ('jane', 'B', 12),
...     ('dave', 'B', 10),
... ]
>>> sorted(stds, key=lambda std: std[2]) # 根据年龄排序  
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

升序降序

list.sort() 和 sorted() 都接受布尔值的 reverse 参数。这用于标记降序排序。例如,要以反向 age 顺序获取学生数据。

>>> stds = [ # 姓名,成绩,年龄
...     ('john', 'A', 15),
...     ('jane', 'B', 12),
...     ('dave', 'B', 10),
... ]
>>> sorted(stds, key=lambda std: std[2], reverse=True)
[('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]

字典排序

字典的 .items() 方法是可迭代对象,可以利用 sorted() 函数进行排序。

>>> dt = {'a': 1, 'c': 3, 'b': 5}
>>> sorted(dt.items(), key=lambda x: x[0]) # 按键排序,返回列表
[('a', 1), ('b', 5), ('c', 3)]
>>> sorted(dt.items(), key=lambda x: x[1]) # 按值排序,返回列表
[('a', 1), ('c', 3), ('b', 5)]

Operator 模块函数(拓展知识,不必掌握)

上面展示的键函数模式非常常见,因此 Python 提供了更方便的函数,使访问器函数更容易、更快捷。operator 模块有 itemgetter() 、 attrgetter() 和 methodcaller() 函数。

使用这些函数,上述示例会变得更简单、更快捷:

>>> from operator import itemgetter, attrgetter
>>> stds = [
...     ('john', 'A', 15),
...     ('jane', 'B', 12),
...     ('dave', 'B', 10),
... ]
>>> sorted(stds, key=itemgetter(2))
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

operator 模块函数允许多级的排序。例如,先按成绩排序,再按年龄排序。

>>> from operator import itemgetter, attrgetter
>>> stds = [ # 姓名,成绩,年龄
...     ('john', 'A', 15),
...     ('jane', 'B', 12),
...     ('dave', 'B', 10),
... ]
>>> sorted(stds, key=itemgetter(1, 2))
[('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]

排序稳定性/复杂度(拓展知识,不必掌握)

排序保证是稳定的。这意味着当多条记录有相同的键时,将保留其原始顺序。

>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=lambda x: x[0])
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

参考

https://docs.python.org/3/howto/sorting.html

你可能感兴趣的:(python,列表,字典,排序)