排序是编程中非常常见的操作,Python 提供了非常强大和灵活的工具。

对 List (列表) 进行排序
对列表排序主要有两种方法:
list.sort()方法:原地排序,会直接修改原始列表,不返回新列表。sorted()内置函数:返回一个新的已排序列表,原始列表保持不变。
这是最核心的区别,请根据你的需求选择。
基础排序:升序
对于简单的数字或字符串列表,使用非常直接。
# 数字列表
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
numbers.sort()
print(f"使用 list.sort() 原地排序: {numbers}") # 输出: [1, 1, 2, 3, 4, 5, 6, 9]
# 字符串列表
fruits = ["banana", "apple", "cherry", "date"]
new_fruits = sorted(fruits)
print(f"使用 sorted() 返回新列表: {new_fruits}") # 输出: ['apple', 'banana', 'cherry', 'date']
print(f"原始列表 fruits 未改变: {fruits}") # 输出: ['banana', 'apple', 'cherry', 'date']
降序排序
两种方法都支持 reverse 参数。

numbers = [3, 1, 4, 1, 5, 9, 2, 6]
numbers.sort(reverse=True)
print(f"降序排序: {numbers}") # 输出: [9, 6, 5, 4, 3, 2, 1, 1]
new_fruits = sorted(fruits, reverse=True)
print(f"降序排序新列表: {new_fruits}") # 输出: ['date', 'cherry', 'banana', 'apple']
核心难点:自定义排序 (Key Function)
当列表元素不是简单的数字或字符串,或者你需要按照特定规则排序时,就需要使用 key 参数。
key 是一个函数,它会被应用于列表的每一个元素上,排序将基于这个函数返回的值,而不是元素本身。
示例1:按绝对值排序
mixed_numbers = [-5, 2, -10, 8, 0, -3]
# 按绝对值升序排序
sorted_by_abs = sorted(mixed_numbers, key=abs)
print(f"按绝对值排序: {sorted_by_abs}")
# 输出: [0, 2, -3, -5, 8, -10]
# 解释: 0(0), 2(2), -3(3), -5(5), 8(8), -10(10)
示例2:对嵌套列表或字典进行排序
这是最常见的自定义排序场景。
对嵌套列表排序
假设我们有一个学生列表,每个学生是一个 [name, score] 的列表,我们想按分数从高到低排序。
students = [
["Alice", 88],
["Bob", 95],
["Charlie", 76],
["David", 85]
]
# 按分数降序排序
# key=lambda x: x[1] 表示取每个子列表的索引为1的元素(即分数)作为排序依据
students.sort(key=lambda student: student[1], reverse=True)
print(students)
# 输出: [['Bob', 95], ['Alice', 88], ['David', 85], ['Charlie', 76]]
lambda 函数:这里我们使用了 lambda(匿名函数),它是一种简洁的、创建单行函数的方式。lambda x: x[1] 等价于:
def get_score(student_list):
return student_list[1]
然后你可以这样写:students.sort(key=get_score, reverse=True)。lambda 通常更方便。
对字典列表排序
这是 极其常见 的情况,假设我们有一个字典列表,想根据字典的某个键来排序。
products = [
{"name": "Laptop", "price": 1200, "stock": 10},
{"name": "Mouse", "price": 25, "stock": 50},
{"name": "Keyboard", "price": 75, "stock": 30}
]
# 按价格升序排序
sorted_by_price = sorted(products, key=lambda item: item["price"])
print("按价格升序:")
print(sorted_by_price)
# 输出:
# [
# {'name': 'Mouse', 'price': 25, 'stock': 50},
# {'name': 'Keyboard', 'price': 75, 'stock': 30},
# {'name': 'Laptop', 'price': 1200, 'stock': 10}
# ]
# 按库存降序排序
sorted_by_stock = sorted(products, key=lambda item: item["stock"], reverse=True)
print("\n按库存降序:")
print(sorted_by_stock)
# 输出:
# [
# {'name': 'Mouse', 'price': 25, 'stock': 50},
# {'name': 'Keyboard', 'price': 75, 'stock': 30},
# {'name': 'Laptop', 'price': 1200, 'stock': 10}
# ]
示例3:多级排序
有时候我们需要先按一个条件排序,如果相同,再按另一个条件排序。
sorted() 和 list.sort() 都支持传入一个 key 函数,该函数返回一个 元组,Python 会按元组的顺序进行比较。
students = [
["Alice", 88, "A"],
["Bob", 95, "A"],
["Charlie", 95, "B"],
["David", 85, "A"]
]
# 先按分数降序,如果分数相同,再按字母顺序升序
# 返回元组 (-score, name) 的技巧可以实现多级排序
# 因为分数是降序,所以取负号后,比较就变成了升序
students.sort(key=lambda s: (-s[1], s[0]))
print(students)
# 输出:
# [
# ['Bob', 95, 'A'],
# ['Charlie', 95, 'B'],
# ['Alice', 88, 'A'],
# ['David', 85, 'A']
# ]
# 解释:
# 1. Bob 和 Charlie 都是 95,比较他们的名字 'Bob' 和 'Charlie','Bob' 排在前面。
# 2. Alice 和 David 分别是 88 和 85,顺序明确。
对 Dict (字典) 进行排序
重要概念:Python 3.7+ 的字典是有序的。 但这里的“排序”通常指的是创建一个新的、按特定顺序排列的字典,或者获取一个已排序的键或值的列表。
直接对字典使用 sort() 或 sorted() 是不行的,因为字典本身是不可变的(不能原地修改其键值对顺序)。
常见的操作是:
- 对字典的键进行排序
- 对字典的值进行排序
- 根据键或值,对字典的项进行排序,并生成一个新字典
对字典的键进行排序
scores = {"Charlie": 95, "Alice": 88, "Bob": 95}
# 获取已排序的键列表
sorted_keys = sorted(scores.keys())
print(f"已排序的键: {sorted_keys}") # 输出: ['Alice', 'Bob', 'Charlie']
# 也可以直接 sorted(scores),因为默认就是遍历键
sorted_keys_2 = sorted(scores)
print(f"已排序的键 (简写): {sorted_keys_2}") # 输出: ['Alice', 'Bob', 'Charlie']
对字典的值进行排序
scores = {"Charlie": 95, "Alice": 88, "Bob": 95}
# 获取已排序的值列表
sorted_values = sorted(scores.values())
print(f"已排序的值: {sorted_values}") # 输出: [88, 95, 95]
根据键或值,对字典的项进行排序并生成新字典
这是最实用的场景,我们可以使用字典推导式 结合 sorted() 来实现。
场景: 我们有一个字典,想根据它的值来排序,并生成一个新的字典。
products = {
"Laptop": 1200,
"Mouse": 25,
"Keyboard": 75
}
# 1. 使用 sorted() 对字典的项进行排序
# dict.items() 返回 (key, value) 对
# 我们想按 value 排序,key=lambda item: item[1]
sorted_items_by_value = sorted(products.items(), key=lambda item: item[1])
print(f"按值排序后的项列表: {sorted_items_by_value}")
# 输出: [('Mouse', 25), ('Keyboard', 75), ('Laptop', 1200)]
# 2. 使用字典推导式将排序后的列表转换回字典
new_sorted_dict_by_value = {k: v for k, v in sorted_items_by_value}
print(f"按值排序后的新字典: {new_sorted_dict_by_value}")
# 输出: {'Mouse': 25, 'Keyboard': 75, 'Laptop': 1200}
按字母顺序对键排序生成新字典:
# 对键排序
sorted_keys = sorted(products.keys())
# 使用字典推导式按排序后的键创建新字典
new_sorted_dict_by_key = {k: products[k] for k in sorted_keys}
print(f"按键排序后的新字典: {new_sorted_dict_by_key}")
# 输出: {'Keyboard': 75, 'Laptop': 1200, 'Mouse': 25}
总结与最佳实践
| 任务 | 推荐方法 | 示例 |
|---|---|---|
| 对列表原地排序 | list.sort() |
my_list.sort() |
| 创建一个新的已排序列表 | sorted() |
new_list = sorted(my_list) |
| 自定义排序规则 | 使用 key 参数 |
sorted(my_list, key=lambda x: x['price']) |
| 多级排序 | key 返回一个元组 |
sorted(my_list, key=lambda x: (-x[1], x[0])) |
| 获取已排序的字典键 | sorted(my_dict.keys()) 或 sorted(my_dict) |
sorted(my_dict) |
| 获取已排序的字典值 | sorted(my_dict.values()) |
sorted(my_dict.values()) |
| 根据值对字典排序并生成新字典 | sorted() + 字典推导式 |
{k: v for k, v in sorted(my_dict.items(), key=lambda item: item[1])} |
sorted() 是一个通用的、返回新序列的函数,适用于任何可迭代对象(列表、元组、字典等),而 list.sort() 是一个列表特有的、原地修改的方法,选择哪个取决于你是否需要保留原始列表。
