Python技巧:列表(list)和字典(dict)排序合集

Python技巧:列表(list)和字典(dict)排序合集

被Python迷倒的大饞貓

排序一直是日常編程中的有用工具。

因此,寫下此文,跟大家一起交流經驗。

Python技巧:列表(list)和字典(dict)排序合集

被Python迷倒的大饞貓

list排序

基本上,你可以使用sort或sorted實現對list的排序。

之間的差異是,sort是直接修改列表中的列表方法,而sorted是原始的創建一個新的列表中的內置功能。

  • 對數字列表進行排序
  • 排序字符串列表
  • 以不區分大小寫的方式對字符串列表進行排序
  • 對元組列表進行排序
  • 按第二個元素對元組列表進行排序
  • 排序對象列表

對數字列表進行排序

在Python中對數字列表進行排序是小菜一碟。

你可以使用sort方法非常輕鬆地對數字列表(整數或浮點數)進行排序。

>>> L = [15, 22.4, 8, 10, 3.14]
>>> L.sort()
>>> L
[3.14, 8, 10, 15, 22.4]

請注意,列表L沒有創建新對象。

如果要創建新的排序列表而不修改原始列表,則應改用sorted功能。

>>> L = [15, 22.4, 8, 10, 3.14]
>>> sorted_list = sorted(L)
>>> L
[15, 22.4, 8, 10, 3.14]
>>> sorted_list
[3.14, 8, 10, 15, 22.4]

正如你可以看到,無論是sort還是sorted,默認情況下為升序排序。

如果要按降序排序,只需將參數reverse = True添加到sort或sorted函數中即可。

這是另一個示例,說明如何以降序方式使用sort方法。

>>> L = [15, 22.4, 8, 10, 3.14]
>>> L.sort(reverse = True)
>>> L
[22.4, 15, 10, 8, 3.14]

對字符串列表進行排序

如果要對字符串列表而不是數字進行排序,你仍然可以使用sort或sorted。基礎用法類似對數字排序,我這裡主要說下含大小寫的處理技巧。

>>> L = ["oranges", "apples", "Bananas"]
>>> L.sort()
>>> L
['Bananas', 'apples', 'oranges']

如你所見,Bananas出現在apples之前,這是有問題的。這樣做的原因是因為Python將所有大寫字母都比小寫字母小。如果這是你想要的,無需進行任何修改。

但是,大多數情況下,在排序時,你希望將字符串視為不區分大小寫。

那麼如何以不區分大小寫的方式對字符串列表進行排序?

從Python 2.4開始,sort和sorted都添加了一個可選的key參數。

此key參數指定在進行比較之前將在每個列表項上調用的函數。

這確實非常有用,因為現在我們可以將str.lower作為key參數傳遞給sort函數。

>>> L = ["oranges", "apples", "Bananas"]
>>> L.sort(key=str.lower)
>>> L
['apples', 'Bananas', 'oranges']

如你所見,現在排序不區分大小寫。

實際上,key參數非常強大,因為它允許我們定義自己的自定義排序功能,我們將在後面看到。

對元組列表進行排序

在深入探討之前,讓我們看看Python如何比較兩個元組。

從第一個元素開始逐個元素地比較元組,這與比較字符串非常相似。

換句話說,你從比較元組的第一個元素開始,如果它們不相等,這就是比較的結果。

如果它們相等,則比較第二個項目,以此類推。

>>> (2, 4) < (4, 1) 
True 
>>> (2, 4) < (2, 6)
True

如果這是你的目的,則只需使用sort方法或sorted函數,兩者都可以正常工作。

>>> sorted([(5, 4), (3, 3), (3, 10)])
[(3, 3), (3, 10), (5, 4)]

但這有時並不是你真正想要的。

例如,假設你有一個元組列表,其中每個元組中的第一個元素代表一個名稱,第二個元素代表年齡。

我們想按年齡對這個元組列表進行排序。如何按第二個元素對元組列表進行排序?

key參數將再次出現。

我們可以通過定義自己的key函數來定義自定義排序。

def custom_sort(t):
 return t[1]
L = [("Alice", 25), ("Bob", 20), ("Alex", 5)]
L.sort(key=custom_sort)
print(L)
# output
# [('Alex', 5), ('Bob', 20), ('Alice', 25)]

如果需要,你甚至可以編寫更整潔的代碼,方法是使用lambdas函數。

L = [("Alice", 25), ("Bob", 20), ("Alex", 5)]
L.sort(key=lambda x: x[1])
print(L)
# output
# [('Alex', 5), ('Bob', 20), ('Alice', 25)]

排序對象(object)列表

那麼,如果你有一個通用對象列表,並且想根據一些自定義條件對這些對象進行排序,那該怎麼辦?

答案是 用 key參數

讓我們舉個例子。

假設你有一個如下所示的User類

class User:
 def __init__(self, name, age):
 self.name = name 
 self.age = age

具有名稱和年齡屬性的簡單類。

讓我們創建一些User對象並將它們添加到列表中。

Bob = User('Bob', 20)
Alice = User('Alice', 30)
Leo = User('Leo', 15)
L = [Bob, Alice, Leo]

現在假設你要按name屬性按字母順序對列表中的對象進行排序。

以下是你可以執行此操作的一種方法:

L.sort(key=lambda x: x.name)
print([item.name for item in L])
# output: 
['Alice', 'Bob', 'Leo']

如果要改為根據age屬性對對象進行排序,則需要執行以下操作:

L.sort(key=lambda x: x.age)
print([item.name for item in L])
# output: 
['Leo', 'Bob', 'Alice']

就像這樣,你可以在可以想到的任何python對象上定義任何自定義排序。

Python技巧:列表(list)和字典(dict)排序合集

字典(dict)排序

Python dict廣泛用於從競爭領域到開發人員領域的許多應用程序(例如,處理JSON數據)。在這種情況下,具有根據其值對字典進行排序的知識可能會很有用。

有兩種方法可以實現這種排序,即

  • 使用lambda函數
  • 使用itemgetter

假設我們有一個字符串和整數的字典,即

#Dictionary of strings and ints
wordsFreqDict = {
 "hello": 56,
 "at" : 23 , 
 "test" : 43, 
 "this" : 43 
} 

字典就像一個哈希表,通過計算鍵的哈希值來存儲元素,並且無法預測元素的順序。因此,它也稱為無序容器,我們可以對字典進行排序。但是我們可以創建一個創建已排序的元組(鍵值)對的列表,也可以按已排序的順序遍歷字典的內容。

  • dict.keys() 按key對字典內容進行排序

一般做法,它返回字典中所有

key的可迭代視圖。

我們將遍歷此排序的鍵列表,並從字典中選擇每個條目,即

for key in sorted(wordsFreqDict.keys()) :
 print(key , " :: " , wordsFreqDict[key])
  • dict.items() 按key對字典內容進行排序

我們還可以使用字典的另一個功能(即items())來實現相同的目的。它的效率更高,它返回一個可重複的元組序列,其中包含字典中的所有鍵值對。

默認情況下,sorted將按元組中的第1個元素(即第0個索引)對元組列表進行排序。因此,元組列表(key/values)按key排序。現在我們可以遍歷該元組的排序列表,即字典中所有排序的key/values,即

for elem in sorted(wordsFreqDict.items()) :
print(elem[0] , " ::" , elem[1] )

就複雜性而言,它比以前的方法更有效,因為在對可迭代序列進行排序之後,我們無需像dict.keys()那樣為鍵搜索值。

我們可以使用List Comprehension實現相同的功能,即

[ print(key , " :: " , value) for (key, value) in sorted(wordsFreqDict.items()) ]

先前的兩種解決方案都是默認按升序對字典進行排序。如果我們想按鍵的降序對內容排序。我們可以像在list排序講到的那樣,在sorted()函數中傳遞屬性,即reverse = True

  • 使用自定義key 按鍵對詞典內容進行排序

我們還可以通過自定義key對字典的內容進行排序。就像我們的list一樣,sorted()函數接受key函數作為參數,並在與其他元素進行比較之前在每個元素上調用它。

因此,要按字符串的長度對字典鍵進行排序,我們將傳遞一個lambda函數作為key函數,該函數將返回字符串的大小,即

listofTuples = sorted(wordsFreqDict.items() , key=lambda x: len (x[0] ) )
 
for elem in listofTuples :
 print(elem[0] , " ::" , elem[1] )

我們也可以使用List Comprehension來做同樣的事情,也可以反序,請參考上文 dict.items()


分享到:


相關文章: