一、sorted()函數概述
sorted()
是Python內置的高階函數,用于對可迭代對象進行排序操作。與列表的sort()
方法不同,sorted()
會返回一個新的已排序列表,而不改變原數據。
基本語法
sorted(iterable, *, key=None, reverse=False)
二、核心參數詳解
1. iterable(必需參數)
任何可迭代對象(列表、元組、字符串、字典等)
2. key(關鍵參數)
- 接受一個函數作為參數
- 該函數會被應用到每個元素上,根據函數返回值進行排序
- 默認值為
None
,表示直接比較元素本身
3. reverse(排序方向)
- 布爾值參數
False
表示升序(默認)True
表示降序
三、底層實現原理
sorted()
內部使用TimSort算法(一種混合了歸并排序和插入排序的穩定算法):
- 時間復雜度:O(n log n)
- 空間復雜度:O(n)
- 穩定性:保持相等元素的原始順序
# 偽代碼展示基本邏輯
def sorted(iterable, key=None, reverse=False):# 1. 獲取可迭代對象的元素列表elements = list(iterable)# 2. 如果有key函數,應用轉換if key is not None:decorated = [(key(x), i, x) for i, x in enumerate(elements)]else:decorated = elements# 3. 執行TimSort排序decorated.sort()# 4. 還原原始數據(保持穩定性)if key is not None:result = [x for (k, i, x) in decorated]else:result = decorated# 5. 處理排序方向if reverse:result.reverse()return result
四、高級使用技巧
1. 復雜對象排序
students = [{'name': 'Alice', 'age': 20, 'score': 85},{'name': 'Bob', 'age': 19, 'score': 92},{'name': 'Charlie', 'age': 21, 'score': 78}
]# 按分數降序排序
sorted_students = sorted(students, key=lambda x: x['score'], reverse=True)
2. 多條件排序
# 先按年齡升序,年齡相同按分數降序
sorted_students = sorted(students,key=lambda x: (x['age'], -x['score']))
3. 使用operator模塊
from operator import itemgetter, attrgetter# 等價于 lambda x: x['score']
sorted_students = sorted(students, key=itemgetter('score'))# 類對象排序
class Student: ...
sorted_students = sorted(students, key=attrgetter('age'))
4. 自定義排序規則
def custom_sort(x):# 奇偶數優先排序:奇數在前,數值小的在前return (x % 2 == 0, x)nums = [3, 1, 4, 2]
sorted_nums = sorted(nums, key=custom_sort) # [1, 3, 2, 4]
五、性能優化建議
- 避免在key函數中進行復雜計算:key函數會被頻繁調用,應保持簡單高效
- 考慮使用生成器:對于大數據集,可以先用生成器預處理
- 預編譯key函數:對于重復使用的key函數,可以預編譯或緩存結果
- 考慮穩定性需求:當需要保持相等元素的原始順序時,sorted()是更好的選擇
六、與sort()方法的對比
特性 | sorted() | list.sort() |
---|---|---|
返回值 | 新列表 | None(原地修改) |
原始數據 | 不改變 | 直接修改 |
適用對象 | 任何可迭代對象 | 僅列表 |
鏈式操作 | 支持 | 不支持 |
內存使用 | 更高(需要副本) | 更低 |
七、實際應用案例
1. 日志文件按時間排序
log_lines = ["2023-01-15 ERROR: Disk full","2023-01-10 INFO: System started","2023-01-12 WARNING: Memory low"
]sorted_logs = sorted(log_lines, key=lambda x: x.split()[0])
2. 文件名自然排序
import refiles = ["file1.txt", "file10.txt", "file2.txt"]
sorted_files = sorted(files, key=lambda x: int(re.search(r'\d+', x).group()))
3. 多語言字符串排序
import locale
locale.setlocale(locale.LC_COLLATE, 'fr_FR.UTF-8')words = ['été', 'h?tel', 'arbre']
sorted_words = sorted(words, key=locale.strxfrm)
八、常見問題解答
Q1: sorted()如何處理None值?
A: 在Python中,None不能與其他值比較。解決方案:
sorted_list = sorted(mixed_list, key=lambda x: (x is None, x))
Q2: 如何實現自定義排序類?
class CustomOrder:_order = ['high', 'medium', 'low']def __init__(self, value):self.value = valuedef __lt__(self, other):return self._order.index(self.value) < self._order.index(other.value)sorted_items = sorted([CustomOrder(x) for x in ['low', 'high', 'medium']])
Q3: 超大文件如何高效排序?
使用外部排序(分塊讀取+歸并):
def external_sort(file_path):# 分塊讀取并排序chunks = []with open(file_path) as f:while True:chunk = list(itertools.islice(f, 10000)) # 每次讀1萬行if not chunk:breakchunk.sort()chunks.append(chunk)# 多路歸并return list(heapq.merge(*chunks))
九、總結
sorted()
作為Python的核心高階函數,其強大之處在于:
- 靈活的參數設計(特別是key函數)
- 穩定的排序算法
- 廣泛的應用場景
- 優秀的性能表現
掌握sorted()
的高級用法,可以讓你寫出更Pythonic、更高效的排序代碼。建議在實際項目中多實踐各種排序場景,深入理解其底層原理。
擴展閱讀:Python官方文檔中關于排序指南的詳細說明