Python sorted 函数
上次修改时间:2025 年 4 月 11 日
本综合指南探讨 Python 的 sorted 函数,该函数从可迭代对象中的项目返回一个新的排序列表。我们将介绍基本用法、自定义排序以及对各种数据结构进行排序的实际示例。
基本定义
sorted 函数从可迭代对象中的项目返回一个新的排序列表。与 list.sort() 不同,它可以与任何可迭代对象一起使用,并返回一个新列表,而不是就地修改。
主要特征:接受任何可迭代对象,返回一个新列表,通过 key 和 reverse 参数支持自定义排序。 它是稳定的(保持相等元素的相对顺序)。
基本排序
这是一个简单的用法,展示了 sorted 如何与不同的可迭代类型一起工作以及 reverse 参数的效果。
# Sorting a list
numbers = [3, 1, 4, 1, 5, 9, 2]
print(sorted(numbers)) # [1, 1, 2, 3, 4, 5, 9]
# Sorting a tuple
letters = ('b', 'a', 'd', 'c')
print(sorted(letters)) # ['a', 'b', 'c', 'd']
# Reverse sorting
print(sorted(numbers, reverse=True)) # [9, 5, 4, 3, 2, 1, 1]
此示例显示了 sorted 与不同的可迭代类型一起使用。 它始终返回一个列表,无论输入类型如何。 reverse 参数控制排序顺序。
请注意,字符串按字典顺序(ASCII/Unicode 顺序)排序。 由于 sorted 创建新列表,因此原始可迭代对象保持不变。
使用 Key 函数自定义排序
key 参数允许自定义排序逻辑。 此示例显示了按字符串长度排序、不区分大小写的排序以及使用 lambda 函数。
words = ["apple", "Banana", "cherry", "date"] print(sorted(words)) # ['Banana', 'apple', 'cherry', 'date'] (case-sensitive) print(sorted(words, key=lambda x: x.lower())) # ['apple', 'Banana', 'cherry', 'date'] # Sort by length print(sorted(words, key=len)) # ['date', 'apple', 'Banana', 'cherry'] # Sort list of tuples by second element pairs = [(1, 'one'), (3, 'three'), (2, 'two')] print(sorted(pairs, key=lambda x: x[1])) # [(1, 'one'), (3, 'three'), (2, 'two')]
key 函数在比较之前转换每个元素。 在这里,我们使用 str.lower 进行不区分大小写的排序,并使用 len 进行基于长度的排序。
Lambda 函数通常与 sorted 一起使用,用于简单的自定义排序逻辑。 转换不会影响结果中的实际值。
排序复杂对象
此示例演示如何使用基于属性的排序以及 key 参数对字典或自定义类等复杂对象进行排序。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person({self.name}, {self.age})"
people = [
Person("Alice", 32),
Person("Bob", 25),
Person("Charlie", 40)
]
# Sort by age
print(sorted(people, key=lambda p: p.age))
# [Person(Bob, 25), Person(Alice, 32), Person(Charlie, 40)]
# Sort by name length
print(sorted(people, key=lambda p: len(p.name)))
# [Person(Bob, 25), Person(Alice, 32), Person(Charlie, 40)]
对于自定义对象,我们通常使用 lambda 函数来提取排序键。 在这里,我们按年龄和姓名长度对 Person 实例进行排序。
相同的方法适用于字典或任何可以定义键提取函数的对象。 原始对象保持不变。
稳定排序属性
Python 的 sorted 是稳定的,这意味着具有相等键的项目保持其原始相对顺序。 此示例演示了多级排序。
# List of tuples (grade, name)
students = [
('B', 'Alice'),
('A', 'Bob'),
('C', 'Charlie'),
('A', 'David')
]
# Sort by grade (primary) and name (secondary)
sorted_students = sorted(students, key=lambda x: x[1]) # Sort by name first
sorted_students = sorted(sorted_students, key=lambda x: x[0]) # Then by grade
print(sorted_students)
# [('A', 'Bob'), ('A', 'David'), ('B', 'Alice'), ('C', 'Charlie')]
要按多个条件排序,我们按照重要性的相反顺序执行排序。 在这里,我们首先按姓名排序,然后按年级排序,并在年级内保持姓名顺序。
稳定性保证意味着不会不必要地重新排列相等的元素。 此属性对于可预测的多级排序至关重要。
性能注意事项
此示例比较了 sorted 与 list.sort() 的性能,并演示了使用不同键函数对大型数据集进行排序。
import timeit
import random
# Generate large dataset
data = [random.randint(0, 1000) for _ in range(10000)]
def test_sorted():
return sorted(data)
def test_sort_method():
lst = list(data)
lst.sort()
return lst
def test_complex_key():
return sorted(data, key=lambda x: (x % 10, x // 10))
print("sorted():", timeit.timeit(test_sorted, number=100))
print("list.sort():", timeit.timeit(test_sort_method, number=100))
print("Complex key:", timeit.timeit(test_complex_key, number=100))
sorted 比 list.sort() 稍慢,因为它必须创建一个新列表。 复杂的键函数会增加与其复杂性成正比的开销。
对于大型数据集,请考虑是否需要新列表或可以就地修改。 优化性能关键型排序操作的键函数。
最佳实践
- 需要不可变性时,首选 sorted: 当您需要一个新的排序列表时
- 就地修改时,使用 list.sort(): 当修改原始对象是可以接受时
- 保持键函数简单: 复杂的键会影响性能
- 利用稳定性: 用于多条件排序
- 考虑 operator 模块: 用于常见的键函数(itemgetter、attrgetter)
资料来源
作者
列出所有 Python 教程。