杰瑞科技汇

Python list、dict如何高效排序?

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

Python list、dict如何高效排序?-图1
(图片来源网络,侵删)

对 List (列表) 进行排序

对列表排序主要有两种方法:

  1. list.sort() 方法:原地排序,会直接修改原始列表,不返回新列表。
  2. 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 参数。

Python list、dict如何高效排序?-图2
(图片来源网络,侵删)
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() 是不行的,因为字典本身是不可变的(不能原地修改其键值对顺序)。

常见的操作是:

  1. 对字典的键进行排序
  2. 对字典的值进行排序
  3. 根据键或值,对字典的项进行排序,并生成一个新字典

对字典的键进行排序

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() 是一个列表特有的、原地修改的方法,选择哪个取决于你是否需要保留原始列表。

分享:
扫描分享到社交APP
上一篇
下一篇