sorted()函数的核心功能是:接收一个可迭代对象(如列表、元组、字符串),返回一个 “新的已排序列表”,且不会修改原始数据。这是它与列表的sort()方法最本质的区别(sort()会直接修改原列表,无返回值)。
1. 基础语法
sorted(iterable, key=None, reverse=False)
iterable:必填参数,待排序的可迭代对象(如列表、元组、字符串、字典等);
key:可选参数,用于指定 “排序依据” 的函数(如key=str.lower忽略字符串大小写排序,key=lambda x: x[1]按元组第二个元素排序);
reverse:可选参数,排序方向,False为升序(默认),True为降序。
2. 最简单的排序案例:数字与字符串
对于基础数据类型(如整数、浮点数、字符串)组成的可迭代对象,sorted()可直接实现排序,无需额外配置:
# 1. 排序数字列表(默认升序)num_list =sorted_nums = sorted(num_list)print("数字升序排序:", sorted_nums) # 输出:[1, 2, 3, 4, 5]print("原始列表是否修改:", num_list) # 输出:[3, 1, 4, 2, 5](未修改)# 2. 降序排序(reverse=True)sorted_nums_desc = sorted(num_list, reverse=True)print("数字降序排序:", sorted_nums_desc) # 输出:[5, 4, 3, 2, 1]# 3. 排序字符串列表(按ASCII码排序,默认小写字母>大写字母)str_list =sorted_strs = sorted(str_list)print("字符串默认排序:", sorted_strs) # 输出:['Banana', 'apple', 'cherry', 'date']# 4. 排序元组(返回的仍是列表)tuple_data = (5, 2, 8, 1)sorted_tuple = sorted(tuple_data)print("元组排序(返回列表):", sorted_tuple) # 输出:[1, 2, 5, 8]print("原始元组是否修改:", tuple_data) # 输出:(5, 2, 8, 1)(元组不可变,自然未修改)
sorted()函数的 “智能” 之处,主要依赖于key和reverse两个参数。尤其是key参数,通过指定自定义函数,可实现对复杂数据类型的灵活排序。
1. reverse 参数:控制排序方向(升序 / 降序)
reverse是布尔值,默认False(升序),设为True时按降序排序。它对所有可排序的数据类型都生效,用法简单但非常实用:
# 降序排序字符串(按ASCII码倒序)str_list = ["a", "c", "b", "d"]sorted_strs_desc = sorted(str_list, reverse=True)print("字符串降序排序:", sorted_strs_desc) # 输出:['d', 'c', 'b', 'a']# 降序排序字典的键(后续会讲字典排序,此处先看reverse的作用)dict_data = {"b": 2, "a": 1, "d": 4, "c": 3}sorted_keys_desc = sorted(dict_data.keys(), reverse=True)print("字典键降序排序:", sorted_keys_desc) # 输出:['d', 'c', 'b', 'a']
2. key 参数:自定义排序依据(最核心的 “智能” 功能)
key参数需要传入一个 “函数对象”,该函数会作用于iterable中的每一个元素,并以函数的返回值作为 “排序依据”。通过key,我们可以实现:按字符串长度排序、按元组指定位置元素排序、按字典指定字段排序等复杂需求。
(1)key = 内置函数:利用 Python 自带函数简化排序
常用的内置函数有len()(按长度)、str.lower()(忽略大小写)、abs()(按绝对值)等:
# 案例1:按字符串长度排序(key=len)str_list = ["apple", "banana", "cherry", "date"] # 长度分别为5、6、6、4sorted_by_len = sorted(str_list, key=len)print("按字符串长度升序:", sorted_by_len) # 输出:['date', 'apple', 'banana', 'cherry']# 案例2:忽略字符串大小写排序(key=str.lower)str_list = ["Apple", "banana", "Cherry", "date"]sorted_ignore_case = sorted(str_list, key=str.lower)print("忽略大小写排序:", sorted_ignore_case) # 输出:['Apple', 'banana', 'Cherry', 'date']# 案例3:按数字绝对值排序(key=abs)num_list = [-3, 1, -4, 2, -5] # 绝对值分别为3、1、4、2、5sorted_by_abs = sorted(num_list, key=abs)print("按绝对值升序:", sorted_by_abs) # 输出:[1, 2, -3, -4, -5]
(2)key=lambda 函数:自定义简单排序规则
当内置函数无法满足需求时,可用lambda表达式定义 “临时排序函数”,实现更灵活的排序依据(如按元组第二个元素、字典某个字段排序):
# 案例1:按元组的第二个元素排序tuple_list = [(1, 3), (4, 1), (2, 5), (3, 2)] # 元组格式:(x, y)sorted_by_second = sorted(tuple_list, key=lambda x: x[1])print("按元组第二个元素升序:", sorted_by_second) # 输出:[(4, 1), (3, 2), (1, 3), (2, 5)]# 案例2:按元组的第一个元素降序(结合reverse)sorted_by_first_desc = sorted(tuple_list, key=lambda x: x[0], reverse=True)print("按元组第一个元素降序:", sorted_by_first_desc) # 输出:[(4, 1), (3, 2), (2, 5), (1, 3)]# 案例3:按字典的"age"字段排序dict_list = [{"name": "Alice", "age": 25},{"name": "Bob", "age": 20},{"name": "Charlie", "age": 30}]sorted_by_age = sorted(dict_list, key=lambda x: x["age"])print("按字典age字段升序:", sorted_by_age)# 输出:[{'name': 'Bob', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Charlie', 'age': 30}]
(3)key = 自定义函数:处理复杂排序逻辑
若排序规则非常复杂(如多条件排序、特殊数据格式处理),可定义独立的函数作为key参数的值:
# 需求:对学生列表排序,先按"成绩"降序,成绩相同则按"年龄"升序def sort_student(student):# 返回元组:(-成绩(降序用负号), 年龄(升序))return (-student["score"], student["age"])student_list = [{"name": "Alice", "score": 90, "age": 20},{"name": "Bob", "score": 85, "age": 22},{"name": "Charlie", "score": 90, "age": 19},{"name": "David", "score": 88, "age": 21}]# 按自定义函数排序sorted_students = sorted(student_list, key=sort_student)print("学生按成绩降序、年龄升序排序:")for student in sorted_students:print(student)# 输出顺序:# {'name': 'Charlie', 'score': 90, 'age': 19}# {'name': 'Alice', 'score': 90, 'age': 20}# {'name': 'David', 'score': 88, 'age': 21}# {'name': 'Bob', 'score': 85, 'age': 22}
sorted()函数支持几乎所有 Python 可迭代对象,包括列表、元组、字符串、字典、集合等。下面针对不同数据类型的排序场景,给出具体实战案例。
1. 场景 1:排序字典(按键、按值、按键值组合)
字典本身是 “无序” 的(Python 3.7 + 后保留插入顺序,但仍需显式排序),sorted()对字典排序时,默认按 “键” 排序,若需按 “值” 排序,需通过key参数指定。
# 原始字典fruit_dict = {"apple": 5, "banana": 2, "cherry": 8, "date": 3}# 1. 按字典的"键"排序(默认,返回键的列表)sorted_keys = sorted(fruit_dict)print("按键升序(默认):", sorted_keys) # 输出:['apple', 'banana', 'cherry', 'date']# 2. 按字典的"值"排序(key=lambda x: fruit_dict[x])sorted_by_value = sorted(fruit_dict, key=lambda x: fruit_dict[x])print("按值升序(返回键):", sorted_by_value) # 输出:['banana', 'date', 'apple', 'cherry']# 3. 按值降序,返回(键, 值)元组列表(用items()获取键值对)sorted_items_desc = sorted(fruit_dict.items(), key=lambda x: x[1], reverse=True)print("按值降序(返回键值对):", sorted_items_desc)# 输出:[('cherry', 8), ('apple', 5), ('date', 3), ('banana', 2)]# 4. 按键的长度排序(key=lambda x: len(x))sorted_by_key_len = sorted(fruit_dict, key=lambda x: len(x))print("按键的长度升序:", sorted_by_key_len) # 输出:['date', 'apple', 'banana', 'cherry'](长度:4,5,6,6)
2. 场景 2:排序嵌套数据(列表嵌套元组 / 字典)
实际开发中,常遇到 “列表嵌套元组” 或 “列表嵌套字典” 的结构(如数据表格、接口返回数据),此时需通过key参数指定嵌套层级的排序依据。
(1)列表嵌套元组(如 CSV 数据)
# 列表嵌套元组:(姓名, 科目, 成绩)score_list = [("Alice", "Math", 90),("Bob", "English", 85),("Charlie", "Math", 95),("David", "English", 88)]# 需求1:按"成绩"降序排序sorted_by_score = sorted(score_list, key=lambda x: x[2], reverse=True)print("按成绩降序:", sorted_by_score)# 输出:[('Charlie', 'Math', 95), ('Alice', 'Math', 90), ('David', 'English', 88), ('Bob', 'English', 85)]# 需求2:先按"科目"升序,再按"成绩"降序sorted_by_subject_score = sorted(score_list, key=lambda x: (x[1], -x[2]))print("先按科目升序,再按成绩降序:", sorted_by_subject_score)# 输出:[('David', 'English', 88), ('Bob', 'English', 85), ('Charlie', 'Math', 95), ('Alice', 'Math', 90)]
(2)列表嵌套字典(如 JSON 数据)
# 列表嵌套字典:接口返回的商品数据product_list = [{"id": 101, "name": "Laptop", "price": 5999, "sales": 120},{"id": 102, "name": "Phone", "price": 3999, "sales": 350},{"id": 103, "name": "Tablet", "price": 2499, "sales": 80},{"id": 104, "name": "Headphone", "price": 799, "sales": 520}]# 需求1:按"销量"降序排序(销量越高越靠前)sorted_by_sales = sorted(product_list, key=lambda x: x["sales"], reverse=True)print("按销量降序:")for product in sorted_by_sales:print(f"{product['name']}: 销量{product['sales']}")# 输出顺序:Headphone(520) → Phone(350) → Laptop(120) → Tablet(80)# 需求2:按"价格"升序排序(价格越低越靠前)sorted_by_price = sorted(product_list, key=lambda x: x["price"])print("\n按价格升序:")for product in sorted_by_price:print(f"{product['name']}: 价格{product['price']}元")# 输出顺序:Headphone(799) → Tablet(2499) → Phone(3999) → Laptop(5999)
3. 场景 3:排序特殊数据类型(字符串、集合、自定义对象)
除了基础数据类型,sorted()还能处理字符串、集合甚至自定义类的实例,只需通过key参数适配排序规则。
(1)排序字符串(按字符 ASCII 码、按长度)
# 排序字符串(默认按字符ASCII码升序,返回字符列表)str_data = "python"sorted_str = sorted(str_data)print("字符串按ASCII码排序:", sorted_str) # 输出:['h', 'n', 'o', 'p', 't', 'y']# 排序字符串列表(按长度降序)str_list = ["hello", "world", "python", "code"]sorted_by_len_desc = sorted(str_list, key=len, reverse=True)print("字符串列表按长度降序:", sorted_by_len_desc) # 输出:['python', 'hello', 'world', 'code'](长度:6,5,5,4)
(2)排序集合(集合是无序的,排序后返回列表)
# 排序集合(集合元素需可比较,如数字、字符串)set_data = {3, 1, 4, 2, 5}sorted_set = sorted(set_data)print("集合排序(返回列表):", sorted_set) # 输出:[1, 2, 3, 4, 5]# 排序字符串集合(按长度排序)str_set = {"apple", "banana", "cherry", "date"}sorted_str_set = sorted(str_set, key=len)print("字符串集合按长度排序:", sorted_str_set) # 输出:['date', 'apple', 'banana', 'cherry'](顺序可能因集合无序略有不同,但长度排序逻辑不变)
(3)排序自定义对象(如类的实例)
对于自定义类的实例,需通过key参数指定 “实例的某个属性” 作为排序依据:
# 定义自定义类:Studentclass Student:def __init__(self, name, age, score):self.name = nameself.age = ageself.score = score# 可选:定义__repr__方法,让打印实例时更清晰def __repr__(self):return f"Student(name='{self.name}', age={self.age}, score={self.score})"# 创建Student实例列表student_instances = [Student("Alice", 20, 90),Student("Bob", 22, 85),Student("Charlie", 19, 95),Student("David", 21, 88)]# 按"score"属性降序排序sorted_by_score = sorted(student_instances, key=lambda x: x.score, reverse=True)print("按Student实例的score降序:")for student in sorted_by_score:print(student)# 输出:# Student(name='Charlie', age=19, score=95)# Student(name='Alice', age=20, score=90)# Student(name='David', age=21, score=88)# Student(name='Bob', age=22, score=85)
很多初学者会混淆sorted()函数和列表的sort()方法,二者都能实现排序,但适用场景不同。下面从 “是否修改原数据”“返回值”“适用对象” 三个维度对比:

实战对比案例
# 1. sorted()函数:适用元组(不可变对象),返回新列表tuple_data = (3, 1, 4, 2)sorted_tuple = sorted(tuple_data)print("sorted()处理元组:", sorted_tuple) # 输出:[1, 2, 3, 4]print("原元组是否修改:", tuple_data) # 输出:(3, 1, 4, 2)(未修改)# 2. list.sort()方法:仅适用列表,修改原列表list_data =sort_result = list_data.sort() # 无返回值,返回Noneprint("list.sort()的返回值:", sort_result) # 输出:Noneprint("原列表是否修改:", list_data) # 输出:[1, 2, 3, 4](已修改)# 3. 选择建议:# - 若需保留原数据,或处理非列表对象(如元组、字典):用sorted()# - 若仅处理列表,且无需保留原数据(节省内存):用list.sort()
在使用sorted()函数时,初学者可能会遇到一些问题,以下是高频问题及解决方案。
1. 问题 1:“TypeError: '<' not supported between instances of 'int' and'str'”
原因:待排序的可迭代对象中包含 “不可比较” 的类型(如同时有整数和字符串),Python 无法判断如何排序。
示例:
# 错误案例:列表中同时有整数和字符串mixed_list = [3, "1", 2, "4"]# sorted(mixed_list) # 执行会报错:TypeError: '<' not supported between instances of 'str' and 'int'
解决方案:
方案 1:统一数据类型(如全部转为整数或全部转为字符串);
# 全部转为整数后排序sorted_mixed = sorted(mixed_list, key=lambda x: int(x))print("统一转为整数排序:", sorted_mixed) # 输出:['1', 2, 3, '4'](注意:原元素类型未变,仅按转换后的值排序)
方案 2:按 “类型优先级” 排序(如先排整数,再排字符串);
# 先按类型排序(整数在前,字符串在后),再按值排序sorted_mixed_type = sorted(mixed_list, key=lambda x: (type(x).__name__, int(x)))print("按类型+值排序:", sorted_mixed_type) # 输出:[2, 3, '1', '4'](int类型在前,str类型在后)
2. 问题 2:排序字典时,无法直接按值排序
原因:sorted()对字典排序时,默认迭代 “键”(dict.keys()),若需按 “值” 排序,需显式指定key参数。
解决方案:
按值排序时,通过lambda x: dict[x]指定排序依据,或用dict.items()获取键值对后按第二个元素排序:
dict_data = {"a": 3, "b": 1, "c": 2}# 按值排序(返回键的列表)sorted_by_value = sorted(dict_data, key=lambda x: dict_data[x])print("按值排序(返回键):", sorted_by_value) # 输出:['b', 'c', 'a']# 按值排序(返回键值对元组列表)sorted_items = sorted(dict_data.items(), key=lambda x: x[1])print("按值排序(返回键值对):", sorted_items) # 输出:[('b', 1), ('c', 2), ('a', 3)]
3. 问题 3:多条件排序时,顺序错误
原因:多条件排序的key参数返回元组时,“条件顺序” 决定了排序优先级(元组第一个元素优先,第一个相同则比较第二个,以此类推),若顺序设置错误,会导致排序结果不符合预期。
示例:
# 需求:先按"成绩"降序,再按"年龄"升序,但错误地将年龄放在前面student_list = [{"name": "Alice", "score": 90, "age": 20},{"name": "Charlie", "score": 90, "age": 19}]# 错误的key设置:先按年龄,再按成绩(与需求相反)# sorted_wrong = sorted(student_list, key=lambda x: (x["age"], -x["score"]))
解决方案:
按 “需求优先级” 设置元组顺序,降序条件用 “负号” 反转:
# 正确的key设置:先按成绩降序(-x["score"]),再按年龄升序(x["age"])sorted_correct = sorted(student_list, key=lambda x: (-x["score"], x["age"]))print("多条件正确排序:", sorted_correct)# 输出:[{'name': 'Charlie', 'score': 90, 'age': 19}, {'name': 'Alice', 'score': 90, 'age': 20}]
1. 3 个核心优势
通用性强:支持所有可迭代对象(列表、元组、字典、字符串等),无需额外转换;
灵活性高:通过key参数可自定义排序规则,满足复杂场景(如多条件排序、嵌套数据排序);
安全性好:不修改原始数据,返回新的排序列表,避免因排序导致原数据丢失。
2. 1 个选择原则
当需要保留原数据或处理非列表对象时,优先使用sorted();
当仅处理列表且无需保留原数据(追求内存效率)时,可使用list.sort()。
掌握sorted()函数后,你就能轻松应对 Python 中的各类排序需求,从简单的数字列表到复杂的嵌套字典排序,都能通过灵活配置key和reverse参数实现。建议多结合实际数据场景练习,熟练后能大幅提升数据处理效率。

