当前位置: 首页 > news >正文

Python排序函数全面指南:从基础到高级

文章目录

  • Python排序函数全面指南:从基础到高级
    • 1. 两种主要排序方式
    • 2. 基本参数详解
      • 2.1 key参数:自定义排序规则
      • 2.2 reverse参数:控制排序方向
    • 3. 高级排序技巧
      • 3.1 多级排序
      • 3.2 稳定排序
    • 4. 性能考虑
    • 5. 特殊排序场景
      • 5.1 对自定义对象排序
      • 5.2 不区分大小写的字符串排序
    • 6. 排序函数对比表
    • 7. 实用技巧总结

Python排序函数全面指南:从基础到高级

排序是编程中最常用的操作之一,Python提供了多种排序方法。本文将全面介绍Python中的排序函数,包括内置函数sorted()和列表方法sort(),以及它们的关键属性和方法。

1. 两种主要排序方式

Python中有两种主要的排序方法:

方法类型返回值原列表是否改变
sorted()内置函数新排序列表不改变原列表
list.sort()列表方法None改变原列表
# sorted() 示例
numbers = [3, 1, 4, 1, 5, 9, 2]
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # [1, 1, 2, 3, 4, 5, 9]
print(numbers)         # [3, 1, 4, 1, 5, 9, 2] (原列表未改变)# sort() 示例
numbers = [3, 1, 4, 1, 5, 9, 2]
numbers.sort()
print(numbers)  # [1, 1, 2, 3, 4, 5, 9] (原列表已改变)

2. 基本参数详解

2.1 key参数:自定义排序规则

key参数允许你指定一个函数,该函数将应用于每个元素,然后根据函数返回的结果进行排序。

# 按字符串长度排序
words = ["apple", "banana", "cherry", "date"]
sorted_words = sorted(words, key=len)
print(sorted_words)  # ['date', 'apple', 'banana', 'cherry']# 按元组的第二个元素排序
pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')]
sorted_pairs = sorted(pairs, key=lambda x: x[1])
print(sorted_pairs)  # [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')]

2.2 reverse参数:控制排序方向

reverse参数是一个布尔值,决定排序是升序(False)还是降序(True)。

numbers = [3, 1, 4, 1, 5, 9, 2]# 升序排序(默认)
print(sorted(numbers))          # [1, 1, 2, 3, 4, 5, 9]# 降序排序
print(sorted(numbers, reverse=True))  # [9, 5, 4, 3, 2, 1, 1]

3. 高级排序技巧

3.1 多级排序

通过返回元组作为key函数的返回值,可以实现多级排序。

students = [{'name': 'Alice', 'grade': 'A', 'age': 20},{'name': 'Bob', 'grade': 'B', 'age': 19},{'name': 'Charlie', 'grade': 'A', 'age': 21},{'name': 'David', 'grade': 'B', 'age': 20}
]# 先按grade升序,再按age降序
sorted_students = sorted(students, key=lambda x: (x['grade'], -x['age']))
for student in sorted_students:print(student)

3.2 稳定排序

Python的排序是稳定的,这意味着当多个元素具有相同的key时,它们会保持原来的相对顺序。

data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
# 按元组的第二个元素排序
sorted_data = sorted(data, key=lambda x: x[1])
print(sorted_data)
# 输出: [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
# 注意 ('red', 1) 和 ('blue', 1) 保持了原来的顺序

4. 性能考虑

Python使用的排序算法是Timsort,它具有以下特点:

  • 最坏情况时间复杂度:O(n log n)
  • 最好情况时间复杂度:O(n) (当数据已经部分有序时)
  • 空间复杂度:O(n)
import random
import time# 生成一个大列表
big_list = [random.randint(0, 100000) for _ in range(1000000)]# 测量排序时间
start = time.time()
sorted_list = sorted(big_list)
end = time.time()
print(f"排序100万个元素耗时: {end - start:.2f}秒")

5. 特殊排序场景

5.1 对自定义对象排序

可以通过定义__lt__方法或使用key参数对自定义对象排序。

class Student:def __init__(self, name, grade):self.name = nameself.grade = gradedef __repr__(self):return f"{self.name}: {self.grade}"# 定义小于方法,用于比较def __lt__(self, other):return self.grade < other.gradestudents = [Student('Alice', 'A'),Student('Bob', 'C'),Student('Charlie', 'B')
]print(sorted(students))  # 自动使用__lt__方法比较

5.2 不区分大小写的字符串排序

fruits = ['apple', 'Banana', 'cherry', 'Date']
print(sorted(fruits))  # ['Banana', 'Date', 'apple', 'cherry'] (默认区分大小写)
print(sorted(fruits, key=lambda x: x.lower()))  # ['apple', 'Banana', 'cherry', 'Date']

6. 排序函数对比表

特性sorted()list.sort()
适用对象任何可迭代对象仅列表
返回值新排序列表None
原列表改变不改变改变
内存使用更多(创建新列表)较少(原地排序)
使用场景需要保留原列表时不需要原列表时

7. 实用技巧总结

  1. 简单升序排序:直接使用sorted()sort()

    sorted([5, 2, 3, 1, 4])  # [1, 2, 3, 4, 5]
    
  2. 降序排序:添加reverse=True

    sorted([5, 2, 3, 1, 4], reverse=True)  # [5, 4, 3, 2, 1]
    
  3. 复杂对象排序:使用key参数

    sorted(['apple', 'banana', 'cherry'], key=len)  # 按长度排序
    
  4. 多条件排序:返回元组作为key

    sorted(students, key=lambda x: (x['grade'], x['age']))
    
  5. 原地排序:当不需要保留原列表时使用sort()

    lst = [5, 2, 3, 1, 4]
    lst.sort()  # lst现在是[1, 2, 3, 4, 5]
    

掌握这些排序技巧将大大提高你在Python中处理数据的效率和灵活性。记住选择哪种排序方法取决于你的具体需求:是否需要保留原列表,以及排序对象的类型。

http://www.xdnf.cn/news/617419.html

相关文章:

  • 字符编码详解:ASCII、Latin1、Unicode、UTF-8 与 GBK
  • 365打卡第N1周: one-hot编码案例
  • 【数据反哺运营】用Python构建可落地的商品结构分析方法论-某朴超市
  • 【风控】申请评分卡(A卡)模型
  • QString 写时拷贝简介
  • 2025年电工杯B题思路讲解问题一四种算法
  • Java 集合框架核心知识点全解析:从入门到高频面试题(含 JDK 源码剖析)
  • 解决:dpkg: error: dpkg frontend lock is locked by another process
  • Coze工作流-变量聚合模块的应用
  • IEEE 流程
  • OSS对象存储如何避免被攻击恶意刷流量?
  • QT中延时的用法及定时器的用法
  • 异地容灾、热备与冷备:核心概念解析、技术对比及行业解决方案指南
  • 在Android APK中使用WebView加载Vue项目并实现文件导出
  • 电网绝缘子及破损、闪络缺陷YOLO数据集
  • 【工具变量】地级市创新重视程度数据及城市创新重视程度数据(2003-2025年)
  • 旅游信息检索
  • 每日算法-250523
  • 1.2.1+1.2.2计算机硬件的基本组成
  • 通信专业速成solidworks学习记录
  • 有限时间 vs 固定时间 vs 预定时间滑模:稳定性分析与仿真验证方法对比(上)
  • 本地分支git push 报错 fatal: The current branch XXXX has no upstream branch.
  • 负号和连接号的区别?
  • 【C++】20. AVL树的实现
  • Python+requests实现接口自动化测试
  • 机器学习 Day1
  • 【python】局域网内通过python远程重启另一台windows电脑
  • Ntfs!ReadIndexBuffer函数调用Ntfs!NtfsMapStream函数的参数FileOffset为什么是0
  • PPP 流程已经走到启动阶段并且成功进入了 “STAGE_START_PPP
  • Linux PXE批量装机+无人值守技术(自动化装机)