Python利用key參數(shù)進行列表排序
在Python編程中,列表排序是高頻操作。無論是處理用戶輸入的數(shù)據(jù)、分析日志文件,還是實現(xiàn)算法邏輯,排序都能讓數(shù)據(jù)更有序、更易處理。但當列表包含混合類型元素,或需要按特定規(guī)則排序時,直接調用sort()或sorted()可能會報錯或得不到預期結果。這時,key參數(shù)就是解決問題的關鍵——它能自定義排序規(guī)則,讓排序邏輯更靈活。
一、基礎排序:默認規(guī)則的局限性
1.1 默認排序的“陷阱”
Python的列表排序默認按元素自然順序排列。對數(shù)字列表[3, 1, 4, 2],list.sort()或sorted()會按數(shù)值大小升序排列;對字符串列表['banana', 'apple', 'cherry'],則按字母順序排列。但若列表包含混合類型,如['oeasy', 123],直接排序會觸發(fā)TypeError,因為Python無法比較字符串和整數(shù)。
lst = ['oeasy', 123] lst.sort() # 報錯:TypeError: '<' not supported between instances of 'int' and 'str'
1.2 強制類型轉換的“笨辦法”
為解決混合類型排序問題,可先將所有元素轉為同一類型(如字符串),再排序。例如:
lst = ['oeasy', 123] lst.sort(key=str) # 將所有元素轉為字符串后比較 print(lst) # 輸出:['123', 'oeasy'](因為 '123' < 'oeasy')
但這種方法并非萬能。若嘗試將字符串轉為整數(shù)(如['999', '123']轉為[999, 123]后排序),對無法轉換的字符串(如['oeasy', '123'])會報錯。因此,強制類型轉換僅適用于能安全轉換的場景。
二、key參數(shù):自定義排序的“魔法棒”
2.1 key參數(shù)的作用原理
key參數(shù)接受一個函數(shù),該函數(shù)會對列表中的每個元素進行處理,返回一個用于比較的值。排序時,Python會根據(jù)key函數(shù)返回的值而非元素本身進行比較。例如,按字符串長度排序時,key=len會讓Python比較字符串長度而非字母順序。
words = ['apple', 'banana', 'cherry', 'date'] words.sort(key=len) print(words) # 輸出:['date', 'apple', 'banana', 'cherry'](長度3 < 5 < 6)
2.2 常見場景:按特定規(guī)則排序
場景1:忽略大小寫排序
默認字符串排序區(qū)分大小寫(大寫字母排在小寫字母前)。若需忽略大小寫,可用str.lower作為key函數(shù):
words = ['Banana', 'apple', 'Cherry', 'date'] words.sort(key=str.lower) print(words) # 輸出:['apple', 'Banana', 'Cherry', 'date']
場景2:按字典的某個鍵排序
對包含字典的列表,可通過key指定排序依據(jù)的鍵。例如,按字典的'age'鍵升序排序:
data = [ {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}, {'name': 'Charlie', 'age': 20}]
sorted_data = sorted(data, key=lambda x: x['age'])
print(sorted_data)
# 輸出:[{'name': 'Charlie', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]
場景3:按多條件排序
若需先按一個條件排序,再按另一個條件排序,可讓key函數(shù)返回元組。例如,先按年齡升序,再按姓名字母順序排序:
data = [ {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}, {'name': 'Charlie', 'age': 25}]
sorted_data = sorted(data, key=lambda x: (x['age'], x['name']))
print(sorted_data)
# 輸出:[{'name': 'Alice', 'age': 25}, {'name': 'Charlie', 'age': 25}, {'name': 'Bob', 'age': 30}]
場景4:按對象屬性排序
對自定義類的對象列表,可通過key指定排序依據(jù)的屬性。例如:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"{self.name}({self.age})"
people = [Person('Alice', 25), Person('Bob', 22), Person('Charlie', 24)]
sorted_people = sorted(people, key=lambda p: p.age)
print(sorted_people) # 輸出:[Bob(22), Charlie(24), Alice(25)]
2.3 高級技巧:自定義函數(shù)與operator模塊
自定義函數(shù)作為key
若排序邏輯復雜,可定義獨立函數(shù)作為key。例如,按字典的'age'鍵加權排序:
def custom_key(item):
return item['age'] * 2 + len(item['name']) # 年齡乘2加姓名長度
data = [
{'name': 'Alice', 'age': 25},
{'name': 'Bob', 'age': 30},
{'name': 'Charlie', 'age': 20}
]
sorted_data = sorted(data, key=custom_key)
print(sorted_data)
# 輸出:[{'name': 'Charlie', 'age': 20}, {'name': 'Alice', 'age': 25}, {'name': 'Bob', 'age': 30}]
使用operator模塊
Python的operator模塊提供了itemgetter和attrgetter函數(shù),可簡化key函數(shù)的編寫。例如,按字典的'score'鍵排序:
import operator
data = [
{'name': 'Alice', 'score': 88},
{'name': 'Bob', 'score': 92},
{'name': 'Charlie', 'score': 85}
]
sorted_data = sorted(data, key=operator.itemgetter('score'))
print(sorted_data)
# 輸出:[{'name': 'Charlie', 'score': 85}, {'name': 'Alice', 'score': 88}, {'name': 'Bob', 'score': 92}]
對對象列表,可用attrgetter按屬性排序:
import operator
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"{self.name}({self.age})"
people = [Person('Alice', 25), Person('Bob', 22), Person('Charlie', 24)]
sorted_people = sorted(people, key=operator.attrgetter('age'))
print(sorted_people) # 輸出:[Bob(22), Charlie(24), Alice(25)]
三、sort()與sorted():選擇合適的排序工具
3.1 原地排序 vs 創(chuàng)建新列表
list.sort()是列表方法,直接修改原列表,返回None。適用于無需保留原始順序的場景,如數(shù)據(jù)預處理。sorted()是內(nèi)置函數(shù),返回新排序列表,原列表不變。適用于需保留原始數(shù)據(jù)的場景,如展示排序結果后繼續(xù)分析原數(shù)據(jù)。
numbers = [3, 1, 4, 2] sorted_numbers = sorted(numbers) # 返回新列表 print(numbers) # 輸出:[3, 1, 4, 2](原列表未變) print(sorted_numbers) # 輸出:[1, 2, 3, 4] numbers.sort() # 原地排序 print(numbers) # 輸出:[1, 2, 3, 4](原列表已變)
3.2 性能與內(nèi)存考慮
list.sort()因原地操作,無需創(chuàng)建新列表,內(nèi)存效率更高,適合處理大型列表。sorted()需創(chuàng)建新列表,內(nèi)存開銷略大,但代碼更安全(避免意外修改原數(shù)據(jù))。
四、實戰(zhàn)案例:key參數(shù)的靈活應用
案例1:按文件擴展名排序
假設有一個文件列表,需按擴展名排序:
files = ['document.pdf', 'image.png', 'spreadsheet.xlsx', 'notes.txt']
def get_extension(filename):
return filename.split('.')[-1] # 提取擴展名
sorted_files = sorted(files, key=get_extension)
print(sorted_files)
# 輸出:['document.pdf', 'image.png', 'notes.txt', 'spreadsheet.xlsx'](按擴展名字母順序)
案例2:按元組中元素優(yōu)先級排序
對包含元組的列表,需先按第二個元素排序,再按第一個元素排序:
tuples = [('a', 3), ('b', 1), ('c', 2), ('d', 1)]
sorted_tuples = sorted(tuples, key=lambda x: (x[1], x[0]))
print(sorted_tuples)
# 輸出:[('b', 1), ('d', 1), ('c', 2), ('a', 3)](先按第二個元素升序,再按第一個元素字母順序)
案例3:復雜邏輯排序
假設需按以下規(guī)則排序:先按字符串長度降序,長度相同則按字母順序升序:
words = ['apple', 'banana', 'cherry', 'date', 'fig'] sorted_words = sorted(words, key=lambda x: (-len(x), x)) # 長度取負實現(xiàn)降序 print(sorted_words) # 輸出:['banana', 'cherry', 'apple', 'date', 'fig'](長度6 > 5 > 3,長度5的'apple' < 'cherry')
五、總結:key參數(shù)的“核心價值”
- 靈活性:通過自定義
key函數(shù),可實現(xiàn)任意復雜的排序邏輯,如按對象屬性、字典鍵、計算結果等排序。 - 通用性:適用于
list.sort()和sorted(),覆蓋原地排序和創(chuàng)建新列表的需求。 - 可讀性:結合lambda表達式或
operator模塊,代碼簡潔易讀,避免冗長的比較函數(shù)。
掌握key參數(shù)后,Python列表排序將不再受限于默認規(guī)則。無論是處理混合類型數(shù)據(jù)、多條件排序,還是復雜邏輯排序,key都能讓排序變得簡單高效。
到此這篇關于Python利用key參數(shù)進行列表排序的文章就介紹到這了,更多相關Python列表排序內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Django中使用pillow實現(xiàn)登錄驗證碼功能(帶刷新驗證碼功能)
這篇文章主要介紹了Django中使用pillow實現(xiàn)登錄驗證碼功能(帶刷新驗證碼功能),本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
解決selenium模塊利用performance獲取network日志請求報錯的問題(親測有效)
這篇文章主要介紹了解決selenium模塊利用performance獲取network日志請求報錯的問題(親測有效),本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03
下載python中Crypto庫報錯:ModuleNotFoundError: No module named ‘Cry
Crypto不是自帶的模塊,需要下載。下面這篇文章主要給大家介紹了關于下載python中Crypto庫報錯:ModuleNotFoundError: No module named 'Crypto'的解決方法,文中通過圖文介紹的非常詳細,需要的朋友可以參考下。2018-04-04
Python實現(xiàn)從log日志中提取ip的方法【正則提取】
這篇文章主要介紹了Python實現(xiàn)從log日志中提取ip的方法,涉及Python文件讀取、數(shù)據(jù)遍歷、正則匹配等相關操作技巧,需要的朋友可以參考下2018-03-03

