mysqlorderby数字字符串排序_Python中的元组排序和深度比较
比較Python中的東西。這聽起來幾乎是不需要教的,但是我發(fā)現(xiàn)Python的比較運算符經(jīng)常被Python新手誤解和低估。
我們來回顧一下Python的比較運算符如何處理不同類型的對象,然后看看如何使用這些比較運算符來提高代碼的可讀性。
Python中的比較運算符
我這里所說的 “比較運算符”是指相等運算符(== 和 !=)和排序運算符(,>=)。
我們可以用這些運算符來比較數(shù)字,正如你所期望的:
除此之外,我們也可以用這些運算符來比較字符串:
甚至于元組:
許多編程語言都沒有與Python非常靈活的比較運算符等價的運算符。
稍后我們將看一看這些運算符如何處理元組和更復雜的對象,我們先從簡單一點的開始:字符串比較。
Python中的字符串比較
字符串的相等和不相等十分簡單。如果兩個字符串有完全相同的字符,那么它們是相等的:
注意,我忽略了一個非常大的例外: unicode字符。通常有多種方法可以表示相同的文本,在將這些不同的表示視為相等之前,必須對它們進行標準化。為了簡單起見,本文將堅持使用ASCII字符。
字符串的排序是Python中比較有趣的部分:
字符串“pickle”比字符串“python”小,因為我們是按字母順序排序的…大小寫有一部分作用:
字符串“Python”小于“pickle”,因為P小于p。
這里我們與其說是按照字母順序還不如說是按照ASCII- 碼順序排序的 (因為我們在python3中實際是使用unicode-碼)。這些字符串是按照它們的字符的ASCII碼值排序的(ASCII碼中p是112,而P是80)。
從技術上講,Python是比較這些字符的Unicode代碼點(這是ord函數(shù)所做的事情),而這恰好與比較ASCII字符的ASCII碼值結果相同。
字符串的排序規(guī)則是:
使用==操作符比較每個字符串的第n個字符(從第一個字符開始,索引為0);如果它們相等,則對下一個字符重復這個步驟
對于兩個不相等的字符,取具有較低代碼點的字符,并聲明其所在字符串“小于”另一個
如果所有字符都相等,那么字符串也是相等的
如果一個字符串在步驟1中耗盡字符(一個字符串是另一個字符串的“前綴”),則較短的字符串“小于”較長的字符串
Python用于比較字符串的排序算法可能看起來很復雜,但它與字典中使用的排序算法非常相似;不是Python中的字典,而是物理字典(我們在互聯(lián)網(wǎng)出現(xiàn)之前使用的那些東西)。當在字典中對單詞排序時,我們優(yōu)先考慮第一個字符,如果一個單詞是另一個單詞的前綴,那么它就會排在前面。
元組的比較
我們可以問元組是否相等,就像我們可以問字符串是否相等一樣:
但是我們也可以使用排序運算符(,>=)來比較元組:
字符串排序可能有些直觀(我們大多數(shù)人在Python之前就已經(jīng)學習了字母排序),但是元組排序一開始并不那么直觀。但實際上你已經(jīng)對元組排序有點熟悉了,因為元組排序和字符串排序使用相同的算法。
元組排序的規(guī)則(本質(zhì)上與字符串排序相同):
使用==運算符比較每個元組的第n項(從第一個項開始,索引為0);如果它們相等,則對下一項重復這個步驟
對于兩個不相等的項,“小于”的項使包含它的元組也“小于”另一個元組
如果所有項都相等,則元組相等
如果一個元組在步驟1中耗盡了項(一個元組是另一個元組的“子集”),則較短的元組“小于”較長的元組
在Python中,這個算法看起來可能有點像這樣:
注意,我們永遠不會這樣編寫代碼,因為Python已經(jīng)為我們完成了所有這些工作。上面整個函數(shù)與使用
字典排序
這種給予一個迭代中第一項優(yōu)先權并類似于按字母順序的排序方式稱為字典排序。你不需要知道這個短語,但是如果你需要描述Python中排序的工作方式,就可以使用lexicographic這個詞。
字符串和元組是按字典順序排列的,正如我們所見,列表也是這樣:
實際上,Python中的大多數(shù)序列都應該按字典順序排列(range對象是一個例外,因為根本無法對它們進行排序)。
但并不是Python中的所有集合都依賴于字典排序。
字典和集合的比較
Python中的許多對象都可以進行相等比較,但不是都能夠排序。
例如,字典比較“相等”時,它們所有的鍵和值都相同:
但是字典不能使用運算符來排序:
集合也是類似的,除了集合可以使用排序運算符……它們只是不使用這些運算符來排序:
集合重載了這些運算符,以便回答關于一個集合是否是另一個集合的子集還是超集的問題(請參閱文檔中關于集合的部分)。
深度相等
Python中兩種數(shù)據(jù)結構之間的比較往往是深度比較。無論我們是在比較列表、元組、集合還是字典,當我們詢問其中兩個對象是否“相等”時,Python將遞歸遍歷每個子對象并詢問它們是否“相等”。
因此,給定一個字典就可以將其中的元組映射到元組列表:
詢問兩個字典是否相等等價于遞歸地詢問每個鍵值對是否相等:
字典會問它們的每個鍵“你在另一個字典里嗎”,然后問這些鍵對應的每個值“你等于另一個值嗎”。但是,每一個操作都可能(就像在本例中)需要另一層深度的操作:鍵是需要遍歷的元組,而值是需要遍歷的列表。在這種情況下,需要更深入地遍歷這些值,即列表,因為它們包含更多的數(shù)據(jù)結構:元組。
不過,我們不必擔心這些:Python會自動地為我們做這些深入的比較。
雖然你不需要關心深度比較是怎樣進行的,但是,實際上Python的比較深度是輕易就能知道的。。
例如,如果我們有一個帶有x、y和z屬性的類,我們想要在我們的__eq__方法中進行比較,而不是使用這個冗長的布爾表達式:
我們可以將這些值處理成含有3個項的元組,來替代布爾表達式進行比較:
我發(fā)現(xiàn)這更易于閱讀,主要是因為我們在代碼中添加了對稱性:我們有一個==表達式,它的兩邊都有相同類型的對象。
深度排序
這種“深度比較”適用于相等比較,但也適用于排序。
深度排序的例子不如深度相等的例子明顯,但是確定哪些地方可以方便地進行深度排序可以幫助你極大地提高代碼的可讀性。
舉個例子方法:
這個 __lt__ 方法在其類上實現(xiàn)了
上面的__lt__方法會給予last_name優(yōu)先權:只有當這兩個對象的last_name屬性恰好相等時才會檢查first_name。
如果我們想打破這個邏輯,我們可以這樣重寫我們的代碼:
或者,我們也可以使用元組的深度排序來代替:
在這里,我們按照字典順序(首先按照它們的第一個項排序)排列元組。我們的元組正好包含字符串,這些字符串也會按字典順序排序(首先按其第一個字符排序)。因此,我們對這些對象進行了深度排序。
一次按多個屬性排序
在對Python對象排序時,了解Python序列的詞典排序和深度排序非常有用。從Python的角度來看,排序?qū)嶋H上就是一遍又一遍地排列順序。
Python內(nèi)置的sorted函數(shù)接受一個key函數(shù),它可以返回一個相應的key對象,并以此來對這些項進行排序。
這里我們指定了一個key函數(shù),它接受一個單詞并返回一個元組,該元組由兩部分組成:單詞的長度和大小寫規(guī)范化的單詞:
使用上面的key函數(shù),我們可以先根據(jù)水果的長度排序,然后根據(jù)它們的大小寫標準化的等價項排序。所以“jujube”排在第一位,因為它是6個字母(比如longan 和 Loquat),但它按字母順序也是排在longan 和 Loquat之前。
如果我們只是按長度排序,我們會有一個不同的順序:
旁注:在Python中,深度比較實際上早于sorted 函數(shù)的key參數(shù)。在key函數(shù)出現(xiàn)之前,Python開發(fā)者會創(chuàng)建元組列表,對元組列表進行排序,然后從該列表中獲取他們關心的實際值(文檔中對此進行了討論)。
元組排序并不只是適用sorted函數(shù)。任何能看到key函數(shù)的地方都可以考慮使用元組排序。例如min和max函數(shù):
在Python執(zhí)行排序操作的任何地方,你都可以使用Python數(shù)據(jù)結構的深度排序。
深度哈希性 (和不可哈希性)
Python既具有深度相等性,又具有深度可排序性。但是Python的深度比較還不止于此:還有深度哈希性。
這主要是由元組帶來的的。元組可以用作字典中的鍵(正如我們前面看到的),它們可以在集合中使用:
但這只適用于包含不可變值的元組:
包含列表的元組是不可哈希的,因為列表是不可哈希的:元組里邊的每個對象都必須是可哈希的,這樣元組本身才是可哈希的。
因此,雖然包含列表的元組是不可哈希的,但是包含元組的元組是可哈希的:
元組通過分派給它們包含的項的哈希值來計算自身的哈希值:
雖然哈希性是一個很大的主題,但這就是我要說的全部。你不需要真正了解Python中的哈希過程是如何工作的,所以如果你發(fā)現(xiàn)這一部分令人困惑,也沒有關系!
這里的要點是Python支持深度哈希,這就是我們可以使用元組作為字典鍵的原因,也是我們可以在集合中使用元組的原因。
深度比較是一種需要記住的工具
當你有一段以特定順序比較兩個基于子部分的對象的代碼時:
你可以優(yōu)先考慮元組排序:
如果你正在進行很多東西的相等比較時:
你或許可以優(yōu)先考慮深度相等:
如果你需要使用一個帶有由多個部分組成的鍵的字典時,并且這些部分都是可哈希的,你可以使用一個元組:
Python對詞典排序和深度比較的支持常常被來自其他編程語言的人忽視。請記住這些特性:你今天可能不需要它們,但在某個時候它們肯定會派上用場。
英文原文:https://treyhunner.com/2019/03/python-deep-comparisons-and-code-readability/
譯者:天天向上
總結
以上是生活随笔為你收集整理的mysqlorderby数字字符串排序_Python中的元组排序和深度比较的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea显示初始界面_Python基础
- 下一篇: 获取后台集合并遍历_java集合类汇总,