最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python中sorted()排序函數(shù)與自定義排序規(guī)則

 更新時間:2026年07月19日 09:31:12   作者:星河耀銀海  
Python中的sorted()函數(shù)是強大的排序工具,它支持自定義排序規(guī)則,適用于各種數(shù)據(jù)結(jié)構(gòu),本文就來詳細介紹一下排序的使用,感興趣的可以了解一下

一、開篇:排序——數(shù)據(jù)處理的基本功

排序是編程中最常見的操作之一。Python提供了兩個排序工具:list.sort()(原地排序)和sorted()(返回新排序結(jié)果)。其中sorted()更靈活、更通用——它能排序任何可迭代對象,還能自定義排序規(guī)則。

?? 先看最基礎(chǔ)的用法:

# sorted()的基本用法
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # [1, 1, 2, 3, 4, 5, 6, 9]
print(numbers)          # [3, 1, 4, 1, 5, 9, 2, 6]  ← 原列表不變!

# list.sort()——原地排序,直接修改原列表
numbers.sort()
print(numbers)          # [1, 1, 2, 3, 4, 5, 6, 9]  ← 被修改了

# ?? 關(guān)鍵區(qū)別:
# sorted(iterable)  → 返回新列表,原數(shù)據(jù)不變,可用于任何可迭代對象
# list.sort()       → 原地排序,不返回新列表,只能用于列表

?? sorted()的核心優(yōu)勢在于它的key參數(shù)——讓你能按任意規(guī)則排序,這個參數(shù)是Python排序系統(tǒng)的靈魂。

二、sorted()的基本參數(shù)

2.1 三個參數(shù)詳解

# sorted(iterable, key=None, reverse=False)
# iterable: 要排序的可迭代對象
# key: 排序依據(jù)的函數(shù)(接收每個元素,返回用于比較的值)
# reverse: 是否降序(True=降序,F(xiàn)alse=升序)

# reverse參數(shù)——升降序控制
numbers = [3, 1, 4, 1, 5]
print(sorted(numbers))             # [1, 1, 3, 4, 5]  升序
print(sorted(numbers, reverse=True))  # [5, 4, 3, 1, 1]  降序

# key參數(shù)——自定義排序依據(jù)
words = ["banana", "apple", "Cherry", "date", "Elderberry"]

# 默認排序——按Unicode碼點(大寫字母在小寫字母前)
print(sorted(words))
# ['Cherry', 'Elderberry', 'apple', 'banana', 'date']

# 按字母順序(忽略大小寫)
print(sorted(words, key=str.lower))
# ['apple', 'banana', 'Cherry', 'date', 'Elderberry']

# 按單詞長度排序
print(sorted(words, key=len))
# ['date', 'apple', 'banana', 'Cherry', 'Elderberry']

2.2 key參數(shù)的詳解

# ?? key函數(shù)的規(guī)則:
# 1. key接收一個參數(shù)(序列中的每個元素)
# 2. key返回一個用于比較的值
# 3. 排序根據(jù)key的返回值進行(不是原始元素)
# 4. 原始元素不變——只是排序的依據(jù)變了

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

# 按字符串中數(shù)字的大小排序
codes = ["item2", "item10", "item1", "item20"]
print(sorted(codes))
# ['item1', 'item10', 'item2', 'item20']  ← 字典序!item10在item2前!

import re
def extract_number(s):
    """提取字符串中的數(shù)字"""
    match = re.search(r'\d+', s)
    return int(match.group()) if match else 0

print(sorted(codes, key=extract_number))
# ['item1', 'item2', 'item10', 'item20']  ← 按數(shù)字大小排!

# 按時間排序
times = ["2024-03-15", "2023-12-01", "2024-01-20", "2023-06-10"]
print(sorted(times))  # 字符串比較恰好對日期格式有效!
# ['2023-06-10', '2023-12-01', '2024-01-20', '2024-03-15']

三、lambda作為key——最常用的排序方式

3.1 按字典字段排序

# ?? 排序字典列表——職場中最常用的技能

employees = [
    {"name": "張三", "age": 28, "salary": 15000, "department": "技術(shù)部"},
    {"name": "李四", "age": 35, "salary": 20000, "department": "管理部"},
    {"name": "王五", "age": 22, "salary": 12000, "department": "技術(shù)部"},
    {"name": "趙六", "age": 30, "salary": 18000, "department": "市場部"},
    {"name": "錢七", "age": 25, "salary": 13000, "department": "技術(shù)部"},
]

# 按年齡排序
by_age = sorted(employees, key=lambda e: e["age"])
print("按年齡:", [e["name"] for e in by_age])
# ['王五', '錢七', '張三', '趙六', '李四']

# 按薪資降序
by_salary = sorted(employees, key=lambda e: e["salary"], reverse=True)
print("按薪資降序:", [(e["name"], e["salary"]) for e in by_salary])
# [('李四', 20000), ('趙六', 18000), ('張三', 15000), ('錢七', 13000), ('王五', 12000)]

# 按年齡排序,同年齡按薪資降序(多級排序)
by_age_salary = sorted(employees, key=lambda e: (e["age"], -e["salary"]))
print("年齡+薪資:", [(e["name"], e["age"], e["salary"]) for e in by_age_salary])

3.2 多級排序

# ?? 多級排序:key返回一個元組
# Python按元組的元素順序依次比較

# 先按部門,再按薪資降序
results = sorted(employees, key=lambda e: (e["department"], -e["salary"]))
for e in results:
    print(f"  {e['department']} - {e['name']}: ¥{e['salary']}")
# 管理部 - 李四: ¥20000
# 技術(shù)部 - 張三: ¥15000
# 技術(shù)部 - 錢七: ¥13000
# 技術(shù)部 - 王五: ¥12000
# 市場部 - 趙六: ¥18000

# ?? 技巧:降序字段用負號
# 數(shù)字降序:-e["salary"](注意:這只對數(shù)字有效)
# 字符串降序:沒法用負號,需要分兩次排序或用functools.cmp_to_key

# 多級排序的另一種方法:多次sorted()(利用穩(wěn)定性)
# Python的排序是穩(wěn)定的——相同key的元素保持原來的相對順序
# 先按次要key排,再按主要key排
result = sorted(employees, key=lambda e: e["salary"], reverse=True)
result = sorted(result, key=lambda e: e["department"])
# 結(jié)果:同一部門內(nèi),按薪資降序

四、高級排序技巧

4.1 使用operator模塊

from operator import itemgetter, attrgetter, methodcaller

# itemgetter——獲取字典的指定字段(相當于lambda e: e["key"])
# 比lambda稍快一些,而且更簡潔
by_department = sorted(employees, key=itemgetter("department"))
print([e["department"] for e in by_department])

# itemgetter多級排序
by_dept_salary = sorted(employees, key=itemgetter("department", "salary"))

# attrgetter——獲取對象的屬性
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score

students = [
    Student("Alice", 85),
    Student("Bob", 92),
    Student("Charlie", 78),
]

by_score = sorted(students, key=attrgetter("score"), reverse=True)
for s in by_score:
    print(f"{s.name}: {s.score}")

4.2 自定義對象的排序

from functools import total_ordering

# 方法一:實現(xiàn)比較方法
class Task:
    def __init__(self, name, priority, due_date):
        self.name = name
        self.priority = priority
        self.due_date = due_date

    def __lt__(self, other):
        """小于比較:先按priority,再按due_date"""
        if self.priority != other.priority:
            return self.priority < other.priority
        return self.due_date < other.due_date

    def __repr__(self):
        return f"Task({self.name}, pri={self.priority}, due={self.due_date})"

tasks = [
    Task("寫報告", 2, "2024-06-15"),
    Task("修復Bug", 1, "2024-06-10"),
    Task("開會", 2, "2024-06-12"),
    Task("代碼審查", 1, "2024-06-08"),
]
print(sorted(tasks))
# [Task(代碼審查, pri=1, due=2024-06-08), Task(修復Bug, pri=1, due=2024-06-10),
#  Task(開會, pri=2, due=2024-06-12), Task(寫報告, pri=2, due=2024-06-15)]

# 方法二:使用key(更靈活,不修改類)
tasks_sorted = sorted(tasks, key=lambda t: (t.priority, t.due_date))

五、實戰(zhàn)案例

5.1 日志按時間排序

# 場景:排序雜亂的日志條目
logs = [
    "[2024-03-15 14:30:22] ERROR 數(shù)據(jù)庫連接失敗",
    "[2024-03-15 14:25:10] INFO 服務(wù)器啟動",
    "[2024-03-15 14:32:05] WARNING 內(nèi)存使用率85%",
    "[2024-03-15 14:25:10] DEBUG 加載配置文件",
    "[2024-03-15 14:28:45] INFO 用戶登錄成功",
]

def extract_timestamp(log_line):
    """從日志行中提取時間戳"""
    return log_line[1:20]  # 提取 "[2024-03-15 14:30:22]" 中的時間

sorted_logs = sorted(logs, key=extract_timestamp)
for log in sorted_logs:
    print(log)
# 按時間正序排列

# 對于同時間的日志,按級別排序
LEVEL_PRIORITY = {"DEBUG": 0, "INFO": 1, "WARNING": 2, "ERROR": 3}

def sort_key(log_line):
    timestamp = extract_timestamp(log_line)
    # 提取日志級別
    level = log_line[22:].split()[0]
    priority = LEVEL_PRIORITY.get(level, 99)
    return (timestamp, priority)

sorted_logs = sorted(logs, key=sort_key)

5.2 自然排序

import re

# 人類期望的排序(自然排序):file1, file2, ..., file10, file11
# 而不是字典序:file1, file10, file11, file2, ...

def natural_sort_key(s):
    """自然排序的key函數(shù)"""
    # 將字符串分割為文本和數(shù)字的交替序列
    parts = re.split(r'(\d+)', s)
    # 將數(shù)字部分轉(zhuǎn)為整數(shù)
    return [int(part) if part.isdigit() else part.lower() for part in parts]

files = ["file10.txt", "file1.txt", "file2.txt", "file20.txt", "file11.txt"]
print(sorted(files))
# ['file1.txt', 'file10.txt', 'file11.txt', 'file2.txt', 'file20.txt']  ← 字典序

print(sorted(files, key=natural_sort_key))
# ['file1.txt', 'file2.txt', 'file10.txt', 'file11.txt', 'file20.txt']  ← 自然序

六、總結(jié)

sorted()key參數(shù)是Python排序系統(tǒng)的精髓,它讓你能按任意規(guī)則排序——從簡單的按長度排,到復雜的多字段組合排序。

?? 核心要點:

  1. sorted()返回新列表,list.sort()原地排序
  2. key函數(shù)定義排序依據(jù)——返回什么就按什么排
  3. 元組key實現(xiàn)多級排序——key=lambda x: (x.a, -x.b)
  4. 穩(wěn)定性——兩次sorted可實現(xiàn)復雜排序
  5. lambda + key是最常用的排序方式

? 記住:key返回的不是元素本身,而是用于比較的"排序值"。合理使用key,你能排序任何數(shù)據(jù)結(jié)構(gòu)。

到此這篇關(guān)于Python中sorted()排序函數(shù)與自定義排序規(guī)則的文章就介紹到這了,更多相關(guān)Python中sorted()排序與自定義排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

隆尧县| 梓潼县| 库车县| 闽清县| 中山市| 综艺| 孟连| 阳信县| 古蔺县| 永川市| 光山县| 丹巴县| 鄂州市| 凤冈县| 南乐县| 安陆市| 吉林省| 延安市| 鄯善县| 扶沟县| 安仁县| 冷水江市| 桦川县| 郎溪县| 东乡| 洪江市| 大厂| 石门县| 密云县| 百色市| 溆浦县| 贡山| 曲阜市| 青阳县| 清原| 文昌市| 肃南| 达州市| 泗洪县| 郁南县| 华蓥市|