python中必须掌握的20个核心函数——sorted()函数

sorted()是Python的内置函数,用于对可迭代对象进行排序,返回一个新的排序后的列表,不修改原始对象。

一、sorted()的基本用法

1.1 方法签名

sorted(iterable, *, key=None, reverse=False)
  • iterable:可迭代对象(列表、元组、字符串、字典等)
  • key:排序键函数(可选)
  • reverse:是否反向排序(默认False,升序)

1.2 基础排序示例

# 数字排序
numbers = [3, 1, 4, 1, 5, 9, 2]
print(sorted(numbers))  # [1, 1, 2, 3, 4, 5, 9]

# 字符串排序(按字母顺序)
words = ["banana", "apple", "cherry"]
print(sorted(words))  # ['apple', 'banana', 'cherry']

# 反向排序
print(sorted(numbers, reverse=True))  # [9, 5, 4, 3, 2, 1, 1]

1.3 与list.sort()的区别

numbers = [3, 1, 4, 1, 5]

# sorted() - 返回新列表,原列表不变
sorted_nums = sorted(numbers)
print(sorted_nums)  # [1, 1, 3, 4, 5]
print(numbers)      # [3, 1, 4, 1, 5](未改变)

# list.sort() - 原地排序,返回None
numbers.sort()
print(numbers)      # [1, 1, 3, 4, 5](已修改)

二、高级排序技巧

2.1 使用key参数进行自定义排序

# 按字符串长度排序
words = ["apple", "banana", "cherry", "date"]
print(sorted(words, key=len))  # ['date', 'apple', 'banana', 'cherry']

# 按第二个字符排序
print(sorted(words, key=lambda x: x[1]))  # ['banana', 'date', 'apple', 'cherry']

# 按绝对值排序
numbers = [-5, 3, -1, 4, -2]
print(sorted(numbers, key=abs))  # [-1, -2, 3, 4, -5]

2.2 多级排序

# 先按长度,再按字母顺序
words = ["apple", "banana", "cherry", "date", "fig"]
print(sorted(words, key=lambda x: (len(x), x)))
# ['fig', 'date', 'apple', 'banana', 'cherry']

# 学生数据:先按分数降序,再按姓名升序
students = [
    {"name": "Alice", "score": 85},
    {"name": "Bob", "score": 92},
    {"name": "Charlie", "score": 85}
]

sorted_students = sorted(students, key=lambda x: (-x["score"], x["name"]))
print(sorted_students)
# [{'name': 'Bob', 'score': 92}, {'name': 'Alice', 'score': 85}, {'name': 'Charlie', 'score': 85}]

2.3 使用attrgetter和itemgetter

from operator import itemgetter, attrgetter

# 对字典列表排序
data = [{"name": "Alice", "age": 25}, {"name": "Bob", "age": 20}]
print(sorted(data, key=itemgetter("age")))  # 按age排序

# 对对象列表排序
class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
    def __repr__(self):
        return f"Person({self.name}, {self.age})"

people = [Person("Alice", 25), Person("Bob", 20)]
print(sorted(people, key=attrgetter("age")))  # 按age属性排序

三、实际应用场景

3.1 数据处理与分析

# 销售数据排序
sales = [
    {"product": "A", "revenue": 1000},
    {"product": "B", "revenue": 2500},
    {"product": "C", "revenue": 1500}
]

# 按收入降序排序
top_sellers = sorted(sales, key=lambda x: x["revenue"], reverse=True)
print(top_sellers)  # B, C, A

3.2 文件内容排序

# 读取文件并排序
with open("data.txt") as f:
    lines = sorted(f.readlines())  # 按字母顺序排序行

# 按数字排序文件内容
with open("numbers.txt") as f:
    numbers = sorted([int(line.strip()) for line in f])

3.3 复杂数据结构排序

# 嵌套列表排序
matrix = [[3, 2, 1], [6, 5, 4], [9, 8, 7]]
# 按每个子列表的第一个元素排序
sorted_matrix = sorted(matrix, key=lambda x: x[0])
print(sorted_matrix)  # [[3, 2, 1], [6, 5, 4], [9, 8, 7]]

四、性能思考与优化

4.1 排序稳定性

# sorted()是稳定排序(相等元素的相对位置不变)
data = [
    ("apple", 2),
    ("banana", 1),
    ("cherry", 2),
    ("date", 1)
]

# 先按数字排序,再按字母排序(保持一样数字的原始顺序)
result = sorted(data, key=lambda x: x[0])  # 按字母排序
result = sorted(result, key=lambda x: x[1])  # 再按数字排序

print(result)
# [('banana', 1), ('date', 1), ('apple', 2), ('cherry', 2)]

4.2 大型数据排序

# 使用生成器表达式节省内存
large_data = (x for x in range(1000000, 0, -1))
sorted_data = sorted(large_data)  # 依旧需要内存存储结果

# 对于极大文件,思考外部排序
def external_sort(file_path):
    """简单的外部排序示例"""
    chunks = []
    # 分块读取、排序、保存
    # ...实现略...
    return sorted_chunks

五、常见问题解答

5.1 sorted()可以排序哪些对象?

任何可迭代对象,但元素必须支持比较操作:

# 数字和字符串可以排序
print(sorted([3, 1, 2]))      # [1, 2, 3]
print(sorted(["c", "a", "b"])) # ["a", "b", "c"]

# 混合类型不能直接排序
try:
    sorted([1, "a", 2])
except TypeError as e:
    print(f"错误: {e}")  # '<' not supported between instances of 'str' and 'int'

5.2 如何实现降序排序?

numbers = [3, 1, 4, 1, 5]
# 方法1:使用reverse参数
print(sorted(numbers, reverse=True))  # [5, 4, 3, 1, 1]

# 方法2:使用负key(对于数字)
print(sorted(numbers, key=lambda x: -x))  # [5, 4, 3, 1, 1]

5.3 排序时如何处理None值?

data = [3, None, 1, 4, None, 2]
# 方法1:过滤None值
print(sorted([x for x in data if x is not None]))  # [1, 2, 3, 4]

# 方法2:自定义排序键
print(sorted(data, key=lambda x: float('inf') if x is None else x))
# [1, 2, 3, 4, None, None]

六、高级技巧

6.1 使用functools.cmp_to_key

from functools import cmp_to_key

# 自定义比较函数(Python 2风格)
def custom_compare(a, b):
    if len(a) != len(b):
        return len(a) - len(b)
    return (a > b) - (a < b)

words = ["apple", "banana", "cherry", "date"]
print(sorted(words, key=cmp_to_key(custom_compare)))
# ['date', 'apple', 'banana', 'cherry']

6.2 处理时区感知的日期时间

from datetime import datetime
import pytz

dates = [
    datetime(2023, 1, 1, tzinfo=pytz.UTC),
    datetime(2023, 1, 1, tzinfo=pytz.timezone("US/Eastern"))
]

# 转换为UTC后排序
sorted_dates = sorted(dates, key=lambda x: x.astimezone(pytz.UTC))

七、总结最佳实践

选择sorted()还是sort()

  • 需要新列表 → sorted()
  • 原地排序 → list.sort()

复杂排序使用key参数

  • 多级排序使用元组key
  • 使用attrgetter/itemgetter提高可读性

性能思考

  • 大型数据注意内存使用
  • 思考使用生成器表达式

错误处理

  • 确保元素可比较
  • 处理None值等特殊情况
# 健壮的排序函数
def safe_sorted(iterable, **kwargs):
    """安全的排序函数,处理异常情况"""
    try:
        return sorted(iterable, **kwargs)
    except TypeError:
        # 处理不可比较的情况
        return sorted(iterable, key=str, **kwargs)  # 转为字符串比较

print(safe_sorted([1, "a", 2]))  # [1, 2, 'a']

sorted()是Python中最强劲和灵活的函数之一,掌握它的各种用法能够极大地提高数据处理能力。

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容