Python列表元素的排序

264 阅读4分钟

一、前言

在 Python 编程中,列表(List) 是最常用的数据结构之一。而对列表进行排序是日常开发中最常见的需求之一,无论是处理数字、字符串还是复杂对象,掌握排序技巧都能显著提升编程效率。

本文将系统性地介绍 Python 中列表排序的方法与技巧,包括内置函数、关键字参数、自定义排序逻辑等,并结合大量代码示例和实际应用场景,帮助你全面掌握列表排序的核心知识。

二、Python 列表排序的基本方式

1. 使用 .sort() 方法 —— 原地排序

.sort() 是列表的一个原地排序方法,会直接修改原始列表:

nums = [5, 2, 9, 1, 7]
nums.sort()
print(nums)  # [1, 2, 5, 7, 9]

✅ 特点:

  • 改变原始列表;
  • 无返回值;
  • 效率高,适合大数据量排序。

2. 使用 sorted() 函数 —— 返回新列表

sorted() 是一个内置函数,不会修改原始列表,而是返回一个新的排序后的列表

nums = [5, 2, 9, 1, 7]
sorted_nums = sorted(nums)
print(sorted_nums)  # [1, 2, 5, 7, 9]
print(nums)         # [5, 2, 9, 1, 7](原列表未改变)

✅ 特点:

  • 不修改原始列表;
  • 返回新列表;
  • 更适合需要保留原始数据的场景。

三、控制排序顺序(升序 / 降序)

默认情况下,Python 按照升序进行排序。可以通过 reverse 参数来控制排序方向:

升序排序(默认)

nums = [5, 2, 9, 1, 7]
nums.sort()
print(nums)  # [1, 2, 5, 7, 9]

降序排序

nums.sort(reverse=True)
print(nums)  # [9, 7, 5, 2, 1]

同样适用于 sorted()

sorted_nums = sorted(nums, reverse=True)

四、对字符串列表排序

Python 默认按照字母顺序(ASCII 值)进行排序:

words = ['banana', 'apple', 'cherry', 'Apricot']
words.sort()
print(words)  # ['Apricot', 'apple', 'banana', 'cherry']

⚠️ 注意:大写字母在 ASCII 表中排在小写字母前面,因此 'Apricot' 排在 'apple' 前面。

如果你希望忽略大小写进行排序,可以使用 key=str.lower

words.sort(key=str.lower)
print(words)  # ['apple', 'Apricot', 'banana', 'cherry']

五、自定义排序规则 —— 使用 key 参数

key 参数允许我们传入一个函数,用于生成排序依据的“键”。

示例 1:按字符串长度排序

words = ['apple', 'fig', 'banana', 'pear']
words.sort(key=len)
print(words)  # ['fig', 'pear', 'apple', 'banana']

示例 2:按元组中的某个字段排序

students = [('Alice', 25), ('Bob', 20), ('Charlie', 30)]
students.sort(key=lambda x: x[1])  # 按年龄排序
print(students)  # [('Bob', 20), ('Alice', 25), ('Charlie', 30)]

示例 3:组合多个排序条件(稳定排序)

Python 的排序是稳定的,即当两个元素相等时,它们的相对位置不变。我们可以利用这一点实现多条件排序:

data = [    (2, 'a'),    (1, 'b'),    (2, 'c'),    (1, 'a')]

# 先按第一个字段排序,再按第二个字段排序
data.sort(key=lambda x: (x[0], x[1]))
print(data)  # [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'c')]

六、对自定义对象排序

如果列表中存储的是自定义类的对象,你可以通过 key 参数指定排序依据。

示例:对 Person 对象按年龄排序

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def __repr__(self):
        return f"{self.name}({self.age})"

people = [
    Person("Alice", 30),
    Person("Bob", 25),
    Person("Charlie", 30)
]

people.sort(key=lambda p: (p.age, p.name))  # 先按年龄,再按名字排序
print(people)
# 输出:[Bob(25), Alice(30), Charlie(30)]

七、常见问题与注意事项

问题原因解决方法
混合类型排序报错int 和 str 不能比较确保列表元素类型一致
忽略大小写排序失败默认区分大小写使用 key=str.lower
自定义对象排序出错未提供 key 函数提供 key 或实现 __lt__ 方法
多条件排序顺序混乱未正确嵌套排序条件使用元组 (field1, field2) 作为 key

八、总结对比表

操作方法是否修改原列表特点
原地排序.sort()✅ 是速度快,不占额外内存
非原地排序sorted()❌ 否保留原数据,更安全
控制排序方向reverse=True/False✅ 支持可用于 .sort() 和 sorted()
自定义排序key=func✅ 支持支持 lambda、函数、属性等
忽略大小写排序key=str.lower✅ 支持字符串列表推荐用法
多条件排序key=lambda x: (x.f1, x.f2)✅ 支持利用稳定排序特性
对象排序key=lambda obj: obj.attr✅ 支持需明确指定排序字段

九、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!