相信很多學Python的小伙伴都十分熟悉Python中的字典排序類問題,這裡我就不展開說了,簡單介紹一下該排序問題的要求及做法並且附上代碼。
前提摘要:sort或者sorted函數的參數reverse = False → 升序(默認) / True → 降序
首先是字典排序類問題,舉個簡單的例子。例如,一個字典裡的所有鍵是某個班同學的名字,所有值是對應同學的學積分成績,現在需要大家輸出前十名同學的名字和成績。絕大多數同學會想到利用list(d.items())來構建一個列表對列表進行排序,接著再遍歷列表,輸出相應的信息。下面附上用二維列表解決排序問題的代碼(這裡簡略用學生編號代替學生成績):
import random
s=[]
for i in range(30):
a = []
a.append(i+1)
score=random.randint(10,100)
a.append(score)
s.extend([a])
list = sorted(s,key = lambda x:x[1],reverse = True) #降序排序
for i in range(10): #輸出前十位同學的成績
print("編號為{:02}的同學成績是:{:2}分".format(list[i][0],list[i][1]))
我們輸出前十名同學的成績,結果如下:
這個問題比較簡單,相信大家看代碼就能看懂,下面有一個一開始另我很疑惑的問題,也是一類字典排序問題,但是要求是,首先按照字典的值進行降序排序(reverse=True),如果字典值相同的話,再按照字典的鍵進行升序排序(默認reverse=False),該問題也可以推廣到二維列表的排序問題,為了簡化理解,我就先把字典的值(或者二維列表(兩列))的第一個元素換成字母,也就是,先按照字典的值也就是數字大小進行降序排列,如果兩個數字相等,再按照字典的鍵也就是字母大小升序排序(Unicode編碼)。兩種思路及配套代碼如下:
首先我們創建了一個字典:
第一種思路如下:
我們進行鍵值對的封裝和第一次排序:
l=list(d.items()) #將d的鍵值對封裝成列表放入列表l中
l.sort(reverse=False,key=lambda x:ord(x[0]))
#依據l子列表中的第0個元素(字母)進行升序排序
我們第一次排序是對字母的升序排序,結果如下:
現在字母已經按照要求的升序排列好,現在我們需要做的是第二次排序,也就是對數字的降序排序,由於我們的優先級是:先數字後字母,也就是在數字相同的情況下才對字母進行升序排序。所以我們第二次排序對數字進行降序時不用管前面我們排好的字母順序(也就是考慮優先級),而是在數字相同時(無法對數字進行大小排序時),此時sort函數不做數字上的大小排序,而是按照之前的遍歷順序依次排序,這時我們發現之前對字母的升序排序派上了用場,這時的遍歷順序就是在數字相同下的字母升序,符合題目要求,代碼如下:
l.sort(reverse=True ,key=lambda x:x[1]) #依據l子列表中的第1個元素(數字)進行降序排序
for i in range (5):
print(l[i][0],l[i][1],sep=' ') #將排序結果進行打印
最終結果如下:
第二種思路如下:
除了上述這種方法,我們還可以用sort函數中key參數的一個特殊傳參方式來解決這個問題,原理是:sorted或者sort函數可以根據多個key值進行數據的排序,按照key值傳入的順序依次,當前面元素相同時,根據後面的key值繼續排序。
原理代碼如下:
sorted(ls, key=lambda x:(x[0], x[1]))) #根據元組第0個值升序排序,若第0個值相等則根據第1個值升序排序
sorted(ls, key=lambda x:(x[0], -x[1])))#根據元組第0個值升序排序,若第0個值相等則根據第1個值降序排序
或者用自定義函數解決:
def cmp1(x):
return x[0], x[1]
def cmp2(x):
return x[0], -x[1]
sorted(ls, key=cmp1)) #根據元組第0個值升序排序,若第0個值相等則根據第1個值升序排序
sorted(ls, key=cmp2)) #根據元組第0個值升序排序,若第0個值相等則根據第1個值降序排序
實現上述題目要求代碼如下:
ls = list(d.items())
ls.sort(key = lambda x:(x[1],-ord(x[0])),reverse=True) #按照第1個值降序排排序,若第1個值相同則按照第0個值升序排序
for k in ls:
print(k[0],k[1])
又或者(默認升序):
ls.sort(key = lambda x:(-x[1],ord(x[0]))) #按照第1個值降序排排序,若第1個值相同則按照第0個值升序排序
最終結果均為:
值得注意的是第一種方法是先對字母進行升序排序,再對數字進行降序排序。而第二種方法是直接依據題目要求,先對數字進行降序排序,在數字相同時再對字母進行升序排序。讀者一定要嚴格區分二者的不同點,同時也要盡可能理解該類字典排序問題的算法思維。
如果該篇文章對你有幫助,請記得 點贊+收藏+關注 哦 ~