Python利用key參數(shù)進(jìn)行列表排序
在Python編程中,列表排序是高頻操作。無論是處理用戶輸入的數(shù)據(jù)、分析日志文件,還是實(shí)現(xiàn)算法邏輯,排序都能讓數(shù)據(jù)更有序、更易處理。但當(dāng)列表包含混合類型元素,或需要按特定規(guī)則排序時(shí),直接調(diào)用sort()或sorted()可能會(huì)報(bào)錯(cuò)或得不到預(yù)期結(jié)果。這時(shí),key參數(shù)就是解決問題的關(guān)鍵——它能自定義排序規(guī)則,讓排序邏輯更靈活。
一、基礎(chǔ)排序:默認(rèn)規(guī)則的局限性
1.1 默認(rèn)排序的“陷阱”
Python的列表排序默認(rèn)按元素自然順序排列。對(duì)數(shù)字列表[3, 1, 4, 2],list.sort()或sorted()會(huì)按數(shù)值大小升序排列;對(duì)字符串列表['banana', 'apple', 'cherry'],則按字母順序排列。但若列表包含混合類型,如['oeasy', 123],直接排序會(huì)觸發(fā)TypeError,因?yàn)镻ython無法比較字符串和整數(shù)。
lst = ['oeasy', 123] lst.sort() # 報(bào)錯(cuò):TypeError: '<' not supported between instances of 'int' and 'str'
1.2 強(qiáng)制類型轉(zhuǎn)換的“笨辦法”
為解決混合類型排序問題,可先將所有元素轉(zhuǎn)為同一類型(如字符串),再排序。例如:
lst = ['oeasy', 123] lst.sort(key=str) # 將所有元素轉(zhuǎn)為字符串后比較 print(lst) # 輸出:['123', 'oeasy'](因?yàn)?'123' < 'oeasy')
但這種方法并非萬能。若嘗試將字符串轉(zhuǎn)為整數(shù)(如['999', '123']轉(zhuǎn)為[999, 123]后排序),對(duì)無法轉(zhuǎn)換的字符串(如['oeasy', '123'])會(huì)報(bào)錯(cuò)。因此,強(qiáng)制類型轉(zhuǎn)換僅適用于能安全轉(zhuǎn)換的場(chǎng)景。
二、key參數(shù):自定義排序的“魔法棒”
2.1 key參數(shù)的作用原理
key參數(shù)接受一個(gè)函數(shù),該函數(shù)會(huì)對(duì)列表中的每個(gè)元素進(jìn)行處理,返回一個(gè)用于比較的值。排序時(shí),Python會(huì)根據(jù)key函數(shù)返回的值而非元素本身進(jìn)行比較。例如,按字符串長(zhǎng)度排序時(shí),key=len會(huì)讓Python比較字符串長(zhǎng)度而非字母順序。
words = ['apple', 'banana', 'cherry', 'date'] words.sort(key=len) print(words) # 輸出:['date', 'apple', 'banana', 'cherry'](長(zhǎng)度3 < 5 < 6)
2.2 常見場(chǎng)景:按特定規(guī)則排序
場(chǎng)景1:忽略大小寫排序
默認(rèn)字符串排序區(qū)分大小寫(大寫字母排在小寫字母前)。若需忽略大小寫,可用str.lower作為key函數(shù):
words = ['Banana', 'apple', 'Cherry', 'date'] words.sort(key=str.lower) print(words) # 輸出:['apple', 'Banana', 'Cherry', 'date']
場(chǎng)景2:按字典的某個(gè)鍵排序
對(duì)包含字典的列表,可通過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}]
場(chǎng)景3:按多條件排序
若需先按一個(gè)條件排序,再按另一個(gè)條件排序,可讓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}]
場(chǎng)景4:按對(duì)象屬性排序
對(duì)自定義類的對(duì)象列表,可通過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 高級(jí)技巧:自定義函數(shù)與operator模塊
自定義函數(shù)作為key
若排序邏輯復(fù)雜,可定義獨(dú)立函數(shù)作為key。例如,按字典的'age'鍵加權(quán)排序:
def custom_key(item):
return item['age'] * 2 + len(item['name']) # 年齡乘2加姓名長(zhǎng)度
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ù),可簡(jiǎn)化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}]
對(duì)對(duì)象列表,可用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。適用于無需保留原始順序的場(chǎng)景,如數(shù)據(jù)預(yù)處理。sorted()是內(nèi)置函數(shù),返回新排序列表,原列表不變。適用于需保留原始數(shù)據(jù)的場(chǎng)景,如展示排序結(jié)果后繼續(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ù))。
四、實(shí)戰(zhàn)案例:key參數(shù)的靈活應(yīng)用
案例1:按文件擴(kuò)展名排序
假設(shè)有一個(gè)文件列表,需按擴(kuò)展名排序:
files = ['document.pdf', 'image.png', 'spreadsheet.xlsx', 'notes.txt']
def get_extension(filename):
return filename.split('.')[-1] # 提取擴(kuò)展名
sorted_files = sorted(files, key=get_extension)
print(sorted_files)
# 輸出:['document.pdf', 'image.png', 'notes.txt', 'spreadsheet.xlsx'](按擴(kuò)展名字母順序)
案例2:按元組中元素優(yōu)先級(jí)排序
對(duì)包含元組的列表,需先按第二個(gè)元素排序,再按第一個(gè)元素排序:
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)](先按第二個(gè)元素升序,再按第一個(gè)元素字母順序)
案例3:復(fù)雜邏輯排序
假設(shè)需按以下規(guī)則排序:先按字符串長(zhǎng)度降序,長(zhǎng)度相同則按字母順序升序:
words = ['apple', 'banana', 'cherry', 'date', 'fig'] sorted_words = sorted(words, key=lambda x: (-len(x), x)) # 長(zhǎng)度取負(fù)實(shí)現(xiàn)降序 print(sorted_words) # 輸出:['banana', 'cherry', 'apple', 'date', 'fig'](長(zhǎng)度6 > 5 > 3,長(zhǎng)度5的'apple' < 'cherry')
五、總結(jié):key參數(shù)的“核心價(jià)值”
- 靈活性:通過自定義
key函數(shù),可實(shí)現(xiàn)任意復(fù)雜的排序邏輯,如按對(duì)象屬性、字典鍵、計(jì)算結(jié)果等排序。 - 通用性:適用于
list.sort()和sorted(),覆蓋原地排序和創(chuàng)建新列表的需求。 - 可讀性:結(jié)合lambda表達(dá)式或
operator模塊,代碼簡(jiǎn)潔易讀,避免冗長(zhǎng)的比較函數(shù)。
掌握key參數(shù)后,Python列表排序?qū)⒉辉偈芟抻谀J(rèn)規(guī)則。無論是處理混合類型數(shù)據(jù)、多條件排序,還是復(fù)雜邏輯排序,key都能讓排序變得簡(jiǎn)單高效。
到此這篇關(guān)于Python利用key參數(shù)進(jìn)行列表排序的文章就介紹到這了,更多相關(guān)Python列表排序內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用python?matplotlib畫折線圖實(shí)例代碼
Matplotlib是一個(gè)Python工具箱,用于科學(xué)計(jì)算的數(shù)據(jù)可視化,下面這篇文章主要給大家介紹了關(guān)于如何使用python?matplotlib畫折線圖的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04
python標(biāo)準(zhǔn)算法實(shí)現(xiàn)數(shù)組全排列的方法
這篇文章主要介紹了python標(biāo)準(zhǔn)算法實(shí)現(xiàn)數(shù)組全排列的方法,實(shí)例分析了全排列的原理與Python實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-03-03
Django+boostrap 美化admin后臺(tái)的操作
這篇文章主要介紹了Django+boostrap 美化admin后臺(tái)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-03-03
PyTorch中torch.nn.functional.cosine_similarity使用詳解
在pytorch中可以使用torch.cosine_similarity函數(shù)對(duì)兩個(gè)向量或者張量計(jì)算余弦相似度,這篇文章主要給大家介紹了關(guān)于PyTorch中torch.nn.functional.cosine_similarity使用的相關(guān)資料,需要的朋友可以參考下2022-03-03
Pandas如何對(duì)Categorical類型字段數(shù)據(jù)統(tǒng)計(jì)實(shí)戰(zhàn)案例
這篇文章主要介紹了Pandas如何對(duì)Categorical類型字段數(shù)據(jù)統(tǒng)計(jì)實(shí)戰(zhàn)案例,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-08-08

