復合條件下的字典排序

2021-10-24 14:17:41 字數 2277 閱讀 8138

知乎上有人說,python3.6以後字典有序且更高效了。群裡有同學推薦了這篇文章給我看,並諮詢字典排序的問題。

大致瀏覽了一下,我當即表示不能認同這個說法。這篇文章的作者,應該是一位資深的專業人士,對於python直譯器如何實現字典儲存和檢索有著深刻地理解。但他犯了一明顯的常識性錯誤:在邏輯上,字典是資料的無序集合,僅依賴於鍵檢索。我們說字典是無序,不是指字典在物理實體上實現的時候真的無序,而是指它的順序對使用者而言沒有明確的界定,不能作為資料的特性使用。知乎上這篇文章講的字典有序,是指字典在物理實體上實現時的有序,而非邏輯上的有序。

既然字典是無序的,為什麼還有那麼多討論字典排序的話題呢?其實,在py2時代,就存在有序字典(orderdict),但有序字典和我們討論的字典,並非一碼事兒。所謂的字典排序,實質上是根據排序規則將字典的鍵排序,得到的排序結果是乙個列表。

我們用乙個例子來演示一下字典排序:roster是乙個儲存學生資訊的字典,請按照女生優先、低年級在前、總成績從高到底排序;如果總成績相同,則順序比較語文、數學、英語成績,高者在前。

roster =

,'鄔勝傑':,

'白星瑤':,

'吳詩涵':,

'莊嘉順'

:}

python最常用的排序函式是sorted(),我們就用sorted()來實現這個排序。如果一次寫出復合排序條件,有一定難度。我們化繁為簡,一步步實現。

>>

>

sorted

(roster, key=

lambda name:roster[name]

['語文'

]+roster[name]

['數學'

]+roster[name]

['英語'])

['吳詩涵'

,'鄔勝傑'

,'莊嘉順'

,'李妍可'

,'白星瑤'

]

看起來沒有問題,但sorted預設是公升序,總成績從高到底排序的話,要使用reverse=true這個引數。

>>

>

sorted

(roster, key=

lambda name:roster[name]

['語文'

]+roster[name]

['數學'

]+roster[name]

['英語'

], reverse=

true)[

'白星瑤'

,'李妍可'

,'鄔勝傑'

,'莊嘉順'

,'吳詩涵'

]

只要在lambda函式中,把排序項並列寫出來,sorted()就會自動實現符合條件排序。這裡性別排序的條件是』性別』==『男』,對女生而言,結果是false(0),小於男生的true(1),自然就排在了前面。

>>

>

sorted

(roster, key=

lambda name:

(roster[name]

['性別']==

'男',roster[name]

['年級'])

)['白星瑤'

,'李妍可'

,'吳詩涵'

,'鄔勝傑'

,'莊嘉順'

]

嘗試了單個條件和兩個條件的排序之後,實現本題目的最終要求就很容易了。不過,成績降序排列的話,不能直接使用reverse=true,因為會影響性別和年級的排序。我們可以稍微變通一下,達到最終的目的。

>>

>

sorted

(roster, key=

lambda name:

( roster[name]

['性別']==

'男',

roster[name]

['年級'],

300-roster[name]

['語文'

]-roster[name]

['數學'

]-roster[name]

['英語'],

100-roster[name]

['語文'],

100-roster[name]

['數學'],

100-roster[name]

['英語'])

)['白星瑤'

,'李妍可'

,'吳詩涵'

,'莊嘉順'

,'鄔勝傑'

]

齊活兒!

字典 選取前100 復合條件下的字典排序

知乎上有人說,python3.6以後字典有序且更高效了。群裡有同學推薦了這篇文章 給我看,並諮詢字典排序的問題。大致瀏覽了一下,我當即表示不能認同這個說法。這篇文章的作者,應該是一位資深的專業人士,對於python直譯器如何實現字典儲存和檢索有著深刻的理解。但他犯了一明顯的常識性錯誤 在邏輯上,字典...

限制條件下計算累加和

question 求 1 2 n 要求不能使用乘除法 for while if else switch case 等關鍵字。ps 無誤,但執行則需要自行整理 沒錯,我就是懶得整理 no.0 三目運算子 class solution no.1 或斷路 class solution no.2 與短路 c...

繼承條件下構造方法的呼叫規則

1 如果子類的構造方法中沒有通過super顯式呼叫父類的有參構造方法,也沒有通過this顯式呼叫自身的其他構造方法,則系統會預設先呼叫父類的無參構造方法。在這種情況下,寫不寫 super 語句,效果是一樣的 2 如果子類的構造方法中通過super顯式呼叫父類的有參構造方法,那將執行父類相應構造方法,...