python sort(建议收藏)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
前言
在编程的世界中,数据的整理与排序如同整理书架上的书籍——杂乱无章的数据难以高效利用,而有序排列的信息则能释放出巨大的价值。Python 提供了灵活且强大的排序工具,无论是简单列表的排序,还是复杂对象的定制化排序需求,都能通过 sort()
方法或 sorted()
函数快速实现。本文将从基础用法到进阶技巧,结合实例与比喻,帮助读者系统掌握 Python 排序的核心逻辑,并理解其底层原理与优化策略。
Python Sort 的基础用法:从简单到复杂
列表的 sort()
方法与 sorted()
函数
Python 提供了两种核心排序工具:列表的 sort()
方法和内置函数 sorted()
。两者的区别在于:
sort()
方法:直接修改原列表,无返回值。sorted()
函数:返回新列表,原列表保持不变。
基础示例
numbers = [3, 1, 4, 1, 5, 9]
numbers.sort()
print(numbers) # 输出:[1, 1, 3, 4, 5, 9]
original = [2, 6, 5, 3]
sorted_list = sorted(original)
print(original) # 输出:[2, 6, 5, 3]
print(sorted_list) # 输出:[2, 3, 5, 6]
比喻:sort()
好比直接整理你的书架,书籍的排列顺序会被永久改变;而 sorted()
则像复制一份书架,保留原书架不变,仅输出整理后的版本。
排序方向:升序与降序
通过 reverse
参数控制排序方向:
numbers = [5, 1, 8, 3]
numbers.sort(reverse=True)
print(numbers) # 输出:[8, 5, 3, 1]
words = ["apple", "banana", "cherry"]
sorted_words = sorted(words, reverse=True)
print(sorted_words) # 输出:['cherry', 'banana', 'apple']
自定义排序规则:用 key
参数灵活控制
默认情况下,Python 对数字按数值大小排序,对字符串按字母顺序排序。但实际场景中,可能需要根据特定规则排序,例如:
- 按字符串长度排序
- 按对象的某个属性排序
- 忽略大小写排序
此时,可以通过 key
参数指定一个函数,将每个元素映射为用于比较的值。
示例 1:按字符串长度排序
fruits = ["apple", "banana", "orange", "kiwi"]
sorted_by_length = sorted(fruits, key=lambda x: len(x))
print(sorted_by_length) # 输出:['kiwi', 'apple', 'banana', 'orange']
sorted_by_length_desc = sorted(fruits, key=lambda x: len(x), reverse=True)
print(sorted_by_length_desc) # 输出:['orange', 'banana', 'apple', 'kiwi']
示例 2:忽略大小写排序
names = ["Alice", "bob", "catherine", "david"]
print(sorted(names)) # 输出:['Alice', 'bob', 'catherine', 'david']
sorted_case_insensitive = sorted(names, key=lambda x: x.lower())
print(sorted_case_insensitive) # 输出:['Alice', 'bob', 'catherine', 'david']
比喻:key
参数如同为每个元素贴上“标签”,排序时仅比较这些标签的值,而原元素本身保持不变。
多级排序:同时基于多个条件排序
在某些场景中,可能需要按多个条件逐级排序。例如:
- 先按分数排序,再按姓名字母顺序排序
- 先按价格排序,再按销量排序
此时可通过 key
参数返回一个元组,元组中的元素按优先级排列:
示例:学生成绩排序
students = [
{"name": "Alice", "score": 85},
{"name": "Bob", "score": 90},
{"name": "Charlie", "score": 85},
{"name": "David", "score": 90}
]
sorted_students = sorted(students, key=lambda x: (x["score"], x["name"]))
for student in sorted_students:
print(f"{student['name']} - {student['score']}")
排序的稳定性:相同键值元素的相对位置
稳定性是排序算法的重要特性:若两个元素的排序键值相同,稳定排序会保留它们在原始列表中的相对顺序,而非稳定排序则可能打乱。
示例:稳定性对比
data = [("apple", 3), ("banana", 2), ("apple", 1), ("cherry", 2)]
sorted_data = sorted(data, key=lambda x: x[0])
比喻:若将排序过程比作整理书籍,稳定性意味着“相同分类的书会保留原有顺序”,而非“随意打乱它们的排列”。
进阶技巧:性能优化与特殊场景
1. 使用 operator
模块提升效率
当需要频繁访问对象属性或列表索引时,使用 operator
模块中的函数(如 itemgetter
、attrgetter
)比 lambda
更高效:
from operator import itemgetter
data = [(3, "c"), (1, "a"), (2, "b"), (3, "d")]
sorted_data = sorted(data, key=itemgetter(1)) # 按第二个元素排序
2. 对象排序:实现 __lt__
方法
若需对自定义对象排序,可通过定义 __lt__
(小于)方法实现:
class Student:
def __init__(self, name, score):
self.name = name
self.score = score
def __lt__(self, other):
# 先按分数降序,再按姓名升序
if self.score != other.score:
return self.score > other.score
else:
return self.name < other.name
students = [
Student("Alice", 85),
Student("Bob", 90),
Student("Charlie", 85)
]
students.sort() # 直接调用 sort() 方法
for student in students:
print(f"{student.name} - {student.score}")
3. 预处理与后处理技巧
对于复杂排序逻辑,可先对数据进行预处理(如添加辅助字段),排序后再恢复原始数据:
words = ["Apple", "banana", "Cherry"]
processed = [(len(word), word.lower(), word) for word in words]
processed.sort(key=lambda x: (x[0], x[1]))
sorted_words = [item[2] for item in processed]
print(sorted_words) # 输出:['Apple', 'Cherry', 'banana']
常见问题与解决方案
问题 1:如何对字典列表按键排序?
people = [
{"name": "Alice", "age": 30},
{"name": "Bob", "age": 25},
{"name": "Charlie", "age": 35}
]
sorted_people = sorted(people, key=lambda x: x["age"])
问题 2:如何反转已排序的结果?
original = [5, 3, 1, 4]
ascending = sorted(original)
descending = ascending[::-1] # 或 sorted(original, reverse=True)
问题 3:如何对嵌套列表按某一列排序?
data = [[3, "c"], [1, "a"], [2, "b"]]
sorted_data = sorted(data, key=lambda x: x[1])
实战案例:电商商品排序
假设我们有一个商品列表,需要按以下规则排序:
- 优先按价格升序;
- 价格相同则按销量降序;
- 销量相同则按名称字母升序。
products = [
{"name": "iPhone", "price": 999, "sales": 500},
{"name": "iPad", "price": 799, "sales": 600},
{"name": "MacBook", "price": 1299, "sales": 400},
{"name": "iPod", "price": 299, "sales": 300},
{"name": "iMac", "price": 1999, "sales": 200},
{"name": "Apple Watch", "price": 399, "sales": 700},
{"name": "AirPods", "price": 159, "sales": 800},
]
sorted_products = sorted(
products,
key=lambda x: (x["price"], -x["sales"], x["name"])
)
for product in sorted_products:
print(f"{product['name']}: ${product['price']} | 销量: {product['sales']}")
输出结果:
AirPods: $159 | 销量: 800
iPod: $299 | 销量: 300
iPad: $799 | 销量: 600
iPhone: $999 | 销量: 500
Apple Watch: $399 | 销量: 700
MacBook: $1299 | 销量: 400
iMac: $1999 | 销量: 200
结论
Python 的排序工具 sort()
和 sorted()
凭借其简洁性与灵活性,成为处理数据的核心技能之一。从基础的升序降序到复杂的多级排序,通过 key
参数和 reverse
参数,开发者能够应对绝大多数场景需求。掌握排序的稳定性、性能优化技巧,以及结合对象或字典的定制化规则,将进一步提升代码的效率与可维护性。
在实际开发中,排序不仅是数据整理的手段,更是算法设计的基础。例如,在搜索引擎中优化搜索结果的排序逻辑,或在数据分析中按特定维度筛选关键信息,都离不开对 Python 排序的深入理解。建议读者通过动手实践案例(如实现购物车价格排序、日志时间排序等),将理论转化为技能,并在项目中逐步探索更高级的技巧。
通过本文的学习,读者应能熟练运用 Python 的排序功能,并在实际开发中灵活应对多样化需求。排序的逻辑或许简单,但其背后蕴含的思维模式与问题解决能力,正是编程进阶的重要基石。