了解 Python 中的排序函数:简单指南

Python中的排序函数:简单指南

Python 的突出优势之一在于其简洁性。 它易于上手的原因在于其标准库内置了众多实用的功能。 排序函数就是其中之一。

此函数用于将可迭代对象按照特定顺序排列。 如果没有这样的函数,就需要编写代码来实现排序算法(例如冒泡排序或插入排序)。 这通常是一项艰巨的任务,但 Python 提供了一种更为简便的方法,本文将对此进行详细阐述。

排序函数简介

sorted 函数是 Python 中用于对可迭代对象进行排序的函数。 可迭代对象是指可以被遍历的任何数据类型,例如字符串、列表、元组和集合。 这些可迭代对象通常是无序的,排序会将它们的值按照指定的规则进行排列。 对值进行排序有很多好处:

  • 排序后的数据可以更快速、更高效地进行搜索,例如使用二分查找算法。 二分查找的前提条件是数据必须先排序。
  • 便于数据的呈现。 用户通常希望按照特定顺序查看信息,例如按价格从低到高或按时间从近到远。 这就需要一种对值列表进行排序的方法。
  • 在执行统计分析时,例如查找一组数据中出现频率最高的值,对排序后的数据进行分析更加便捷。

排序函数的使用方法

如前所述,排序函数适用于所有可迭代对象。 并且,它总是返回一个排序后的列表。 需要注意的是,虽然输入可以是任何可迭代对象,但返回值始终是一个列表。

排序函数的语法

排序函数的标准格式如下:

sorted(iterable, key=None, reverse=False)

可以看到,唯一必需的参数是 iterable,即待排序的可迭代对象。

key 参数用于指定一个函数,该函数会将可迭代对象中的每个元素转换成一个用于排序的值。 这个参数在对字典列表进行排序时尤其有用,稍后会进行详细介绍。 默认情况下,该参数为 None,即不使用任何函数进行转换。

reverse 参数用于指定排序顺序。 当设置为 True 时,元素将按降序排序。

在接下来的部分中,我将通过实例演示如何使用这个函数。

排序函数使用示例

数字列表

最简单的排序场景是对数字列表进行排序。 请看以下代码示例:

  # 一个未排序的数值列表
  numbers = [8, 4, 3, 9, 2, 0, 3]

  # 对数字进行排序
  sorted_numbers = sorted(numbers)

  # 输出排序后的数值
  print(sorted_numbers)
  

输出结果为:

[0, 2, 3, 3, 4, 8, 9]

可以看到,数值已经按升序排列。 如果想按降序排序,可以将 reverse 设置为 True。 因此,上述代码示例中的第 4 行可以修改为:

sorted_numbers = sorted(numbers, reverse=True)

修改后的程序的输出结果为:

[9, 8, 4, 3, 3, 2, 0]

字符串列表

排序函数不仅可以处理数字,还可以处理字符串。 对字符串列表进行排序时,会比较字符串的第一个字符。 比较是基于字符的 ASCII 值进行的。 例如,字符串 “hello” 会排在字符串 “world” 的前面,因为 “h” 的 ASCII 值是 104,小于 “w” 的 ASCII 值 119。

如果一个或多个字符串具有相同的第一个字符,则会继续比较它们的第二个字符,以此类推,直到确定顺序。 下面是一个对人名进行排序的代码示例:

  # 创建一个人名列表
  members_list = ['bob', 'dave', 'charlie', 'alice']

  # 对人名进行排序
  sorted_members_list = sorted(members_list)

  # 打印人名
  print(sorted_members_list)
  

输出结果为:

['alice', 'bob', 'charlie', 'dave']

由于是根据 ASCII 值进行排序,字符串的顺序取决于第一个字符在 ASCII 表中的位置。 例如,大写字母会排在小写字母前面,因为大写字母在 ASCII 表中位于小写字母之前。 下面是一个完整的 ASCII 表供您参考:

来源:commons.wikimedia.org

其他可迭代对象——字符串、元组和集合

正如我之前提到的,排序函数可以处理多种可迭代对象。 其排序规则也适用于这些可迭代对象。 下面是一些例子:

  # 打印一个排序后的字符串
  print(sorted("dijkstra"))

  # 打印一个排序后的元组
  print(sorted((3, 4, 2, 1, 5, 0)))

  # 打印一个排序后的集合
  print(sorted(set([4, 5, 5, 1, 3, 8, 9])))
  

其输出结果为:

['a', 'd', 'i', 'j', 'k', 'r', 's', 't']
[0, 1, 2, 3, 4, 5]
[1, 3, 4, 5, 8, 9]

正如您所看到的,每种情况的输出都是一个列表。

字典列表

排序函数也可以用于对字典列表进行排序。 然而,对字典进行排序相对复杂,因为与数字或字符串不同,字典有多个属性,每个属性都可以作为比较的依据。

因此,为了对字典进行排序,需要指定一个函数,将整个字典归纳为一个用于比较的值。 此函数会作为 key 参数传递给排序函数。 以下示例对此进行了说明:

  people = [
        { 'name': 'Alice', 'age': 27 },
        { 'name': 'Bob', 'age':  23 },
        { 'name': 'Charlie', 'age': 25}
  ]

  people_sorted_by_age = sorted(people, key=lambda person: person['age'])
  print(people_sorted_by_age)
  

在这个例子中,我们有一个字典对象列表,每个对象代表一个人,并包含 nameage 属性。 我们希望按照年龄对人进行排序。 因此,在调用 sorted 函数时,我们传递一个函数作为 key 参数。

该函数会接收一个人的字典对象,并返回该人的年龄。 该键的返回值会用于排序。 因此,整个字典会被归纳成一个可以比较的简单整数。 为了简洁起见,我们使用 lambda 函数定义 key 参数。

执行代码后,输出结果如下:

[{'name': 'Bob', 'age': 23}, {'name': 'Charlie', 'age': 25}, {'name': 'Alice', 'age': 27}]

key 参数的用途

key 参数不仅可以在对字典进行排序时使用,还可以应用于所有数据类型。 它的作用是提供一个可用于排序的键。 以下是一些使用场景示例:

  • 通过定义一个函数(该函数接收一个值并返回该值的长度)来实现按长度对值进行排序。
  • 实现对字符串列表的不区分大小写排序。 为此,可以将列表中的每个字符串转换为小写。 这可以通过定义一个函数(该函数接收一个字符串,并返回该字符串的小写版本)来实现。
  • 根据其他元素的组合值对值进行排序。

排序函数的运行时复杂度

排序函数的运行时复杂度为 O(n log n),其中 n 是输入可迭代对象中的元素数量。 产生这种复杂度的原因是该函数使用了 Timsort 算法,它是一种基于归并排序和插入排序的混合排序算法。

该函数的空间复杂度为 O(n),其中 n 仍然是输入中的元素数量。 这是因为会创建一个新的列表作为返回值。

排序函数与 sort 函数

另一种对值进行排序的方法是使用 sort 函数。 本节将解释 sort 函数和 sorted 函数之间的主要区别。

  • sort 函数会直接修改可迭代对象,而 sorted 函数会创建一个新的列表并返回。
  • 由于 sort 函数是直接修改,因此其输入必须是列表。 另一方面,sorted 函数可以接收任何可迭代对象作为输入,并基于该输入创建一个新的列表。

总结

在本文中,我们介绍了 sorted 函数:它是什么、如何使用它以及它接受的不同参数。 我们还介绍了该函数的不同使用示例及其运行时复杂度,并将其与 sort 函数进行了比较。

接下来,您可能对我们关于 Python 的求和函数文章感兴趣。