主要原因,內(nèi)置函數(shù)用C寫的。在Python語言內(nèi)無論如何造不出內(nèi)置函數(shù)的輪子。這也是通常C跟C++語言用戶更喜歡造基礎(chǔ)算法的輪了的原因。因為C/C++用戶真有條件寫出匹敵標(biāo)準(zhǔn)庫的算法,但很多高級語言不行,不是程序員技術(shù)差,是客觀條件就根本做不到。
創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站制作、做網(wǎng)站與策劃設(shè)計,滁州網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:滁州等地區(qū)。滁州做網(wǎng)站價格咨詢:028-86922220
你比如說Java語言沒人造字符串的輪子,C++光一個字符串類就有無數(shù)多的實現(xiàn)。是因為C+用戶更喜歡寫字符串類嗎?顯然不是,一方面是因為Java語言內(nèi)沒法造出匹敵Java內(nèi)置標(biāo)準(zhǔn)庫算法的輪子,而C++真的可以,另外一個比較慘的原因是C++標(biāo)準(zhǔn)庫的字符串功能太弱了,大多數(shù)高級語言的字符串類功能都比C+標(biāo)準(zhǔn)庫字符串類功能更強。
寫C++的時候一大錯覺就是我覺著我能比標(biāo)準(zhǔn)庫還快,同樣的道理放在Python里面也同樣適用,不管是Python各種常用package或內(nèi)建函數(shù),基本上都針對實用場景作了優(yōu)化,自己手寫的算法一般是比不上內(nèi)建算法效率的,這也是為什么用Python時不鼓勵自己造輪子的原因。
回到這個問題,Python內(nèi)建的sort本質(zhì)上為C實現(xiàn)的函數(shù),本身執(zhí)行效率就會比Python快很多,并且會根據(jù)不同的數(shù)據(jù)規(guī)模采用不同的排序算法,故效率一般都會優(yōu)于自己在Python里面手寫的排序更何況題主寫的是基于遞歸的quicksort9,額外時間開銷大。
因為python內(nèi)置的sort是用c語言寫的,如果你用c語言或者c++寫的話肯定是可以做到一樣快的至于為什么python計算效率比c語言能慢100倍這個具體的原理我不清楚,不過鑒于知乎上已經(jīng)有很多大佬解釋過這個問題,我就不在這里班門弄斧了
還有底下扯timsort的,快排序是所有比較排序算法里平均性能最優(yōu)的一族算法,像C++和rust里的unstable_sort都是用的快排序??赡茉谝恍┣闆r下,比如數(shù)組幾乎有序時,timsort會比快排序快。但是你隨便給一個數(shù)組,比如像題主那樣隨機一個一百萬大小的數(shù)然后排序,timsort是絕對不可能比快排序快的。絕對不可能。快的這100倍和timsort屁關(guān)系都沒有。
我是C/C++程序員,我可以很負(fù)責(zé)的告訴你,在用天下現(xiàn)有所有高級語言進行排序的問題上,C要是認(rèn)了第二,則沒人敢認(rèn)第一。所以,我猜,Python以及好多其他高級語言,都會時不時直接上C語言寫的靜態(tài)庫和動態(tài)庫。我自己也造了不少輪子,有部分是因為剛剛起步,對系統(tǒng)API和函數(shù)庫不熟悉,找不到適合的,所以自己造輪子,后來發(fā)現(xiàn)了有更好的,我把我寫的拋棄了。但這里也不排除有一部分是因為我個人覺得還有優(yōu)化的空間,所以自己用C語言重新造了一個輪子,這樣效率比現(xiàn)成的更優(yōu)。
所以說,要論高級語言的鼻祖,還真非C莫屬,從執(zhí)行效率上講,別說python,JAVA,C#,VB,甚至C的親兒子C++,在同一個程序員手中,都沒法與C抗衡,所以說,這些語言都是排著隊等著被C吊打的,也正因為如此,所以,像python這類高級語言,有自帶函數(shù)可用的,最好別想著自己重新造輪子,因為你不可能造出比自帶函數(shù)更快的輪子。
內(nèi)置庫函數(shù)都是用C實現(xiàn)的,肯定要比手寫的Python程序執(zhí)行效率更高,此外內(nèi)置排序Timsort相比本科課程上學(xué)的時間復(fù)雜度為Onlogn的排序算法做了很多常數(shù)優(yōu)化,所以對于普通人而言,不要希望純手寫出來的東西效率能和標(biāo)準(zhǔn)庫相當(dāng)了。另外,題主寫的排序是過不了LeetCode上的裸排序題目的,隨機選取pivot對于快速排序是最基本的優(yōu)化雖然題主排的是隨機數(shù),現(xiàn)在這么選肯定不是效率低的主要原因。
所以說了,py幾乎得把自己的循環(huán)體拆了,這就是py和c/c++的性能差距,必須盡量用內(nèi)置函數(shù)和numpy來處理數(shù)據(jù),一旦手寫循環(huán)體。,那你就得知道這可能得慢百倍,像用opency的py版時你不小心寫個雙循環(huán)來處理數(shù)據(jù),那酸爽,而cppc#搞opencv就能隨意用指針來寫循環(huán),這也是為啥他們其實不需要numpy這種組件,自身就有足夠的性能和靈活度來處理這個。
Cpp內(nèi)置的排序是快排和堆排的結(jié)合,最壞時間復(fù)雜度為nlogn,而快排最壞是n2。至于python內(nèi)部的排序,我認(rèn)為是一個道理,不會簡簡單單是一個快排,舉個簡單例子,當(dāng)你數(shù)據(jù)已經(jīng)是有序的時候,再傳入快排肯定就不合適。那你設(shè)置排序函數(shù)的時候,是不是預(yù)先將他打亂,再進行快排會更好呢。當(dāng)然具體不會這么簡單,只是我認(rèn)為官方給的接口都是很精妙的,很值得學(xué)習(xí)。
一方面Python中sort函數(shù)是用C語言寫的,C++內(nèi)部的sort是由快排,直接插入和堆排序混合的,當(dāng)數(shù)據(jù)量比較大的時候先用的快排,當(dāng)數(shù)據(jù)量小的時候用直接插入,因為當(dāng)數(shù)據(jù)量變小時,快排中的每個部分基本有序,接近直接插入的最好情況的時間復(fù)雜度O(n),就比快排要好一點了。
另外一方面這個的底層實現(xiàn)就是歸并排序。,只是使用了Python無法編寫的底層實現(xiàn),從而避免了Python本身附加的大量開銷,速度比我們自己寫的歸并排序要快很多,所以說我們一般排序都盡量使用sorted和sort。
內(nèi)置函數(shù)就是Python給你提供的,拿來直接用的函數(shù),比如print.,input等。
截止到python版本3.6.2 ,python一共提供了68個內(nèi)置函數(shù),具體如下
本文將這68個內(nèi)置函數(shù)綜合整理為12大類,正在學(xué)習(xí)Python基礎(chǔ)的讀者一定不要錯過,建議收藏學(xué)習(xí)!
(1)列表和元組
(2)相關(guān)內(nèi)置函數(shù)
(3)字符串
frozenset 創(chuàng)建一個凍結(jié)的集合,凍結(jié)的集合不能進行添加和刪除操作。
語法:sorted(Iterable, key=函數(shù)(排序規(guī)則), reverse=False)
語法:fiter(function. Iterable)
function: 用來篩選的函數(shù). 在?lter中會自動的把iterable中的元素傳遞給function. 然后根據(jù)function返回的True或者False來判斷是否保留留此項數(shù)據(jù) , Iterable: 可迭代對象
搜索公眾號頂級架構(gòu)師后臺回復(fù)“面試”,送你一份驚喜禮包。
語法 : map(function, iterable)
可以對可迭代對象中的每一個元素進行映射. 分別去執(zhí)行 function
hash : 獲取到對象的哈希值(int, str, bool, tuple). hash算法:(1) 目的是唯一性 (2) dict 查找效率非常高, hash表.用空間換的時間 比較耗費內(nèi)存
python有兩個內(nèi)置的函數(shù)用于實現(xiàn)排序,一個是list.sort()函數(shù),一個是sorted()函數(shù)。
區(qū)別1:list.sort()函數(shù)只能處理list類型數(shù)據(jù)的排序;sorted()則可以處理多種類型數(shù)據(jù)的排序。
區(qū)別2:list.sort()會修改原來的list為排序后的結(jié)果;sorted()不會修改原來的數(shù)據(jù),只是返回一個排序后的對象。
下面來動手寫點代碼進行測試:
list進行簡單的排序
1 a=['a','f','c','x','e']2 a.sort()3 a4 [a','c','e','f','x']
sorted()進行簡單排序
1 a=['a','f','c','x','e']2 a_new=sorted(a)3 a_new4 ['a', 'c', 'e', 'f', 'x']
list.sort()和sorted都有默認(rèn)的參數(shù)reverse,該參數(shù)的默認(rèn)值為“False”,即默認(rèn)升序排列。如果要進行降序排列:
1 a=['a','f','c','x','e']2 a_new=sorted(a,reverse=True)3 a_new4 ['x', 'f', 'e', 'c', 'a']
對元組進行排列,不能使用list.sort()函數(shù):
1 a=('a','f','c','x','e')2 a_new=a.sort()3
4 ttributeError: 'tuple' object has no attribute 'sort'
對字典的排序可以按照字典的key或者value進行排序:
1 dic={"aa":11,"ff":5,"ee":22}2 printsorted(dic.keys())3 ['aa', 'ee', 'ff']
從python2.4開始list.sort()和sorted()都引入了key參數(shù)來指定一個函數(shù)進行排序,有了key參數(shù)以后我們就可以對更加復(fù)雜的數(shù)據(jù)進行排序 。
假如需要排序的數(shù)據(jù)為一個list,但list的每一個元素都是一個字典,排序的方法如下:
dic=[{"name":"sunny","age":20},
{"name":"bell","age":5},
{"name":"jim","age":1},
{"name":"jan","age":10}]print sorted(dic,key=lambda arg:arg.get('age'),reverse=False) #按照每個字典的age的值進行排序,字典的方法dict.get(key)將返回指定鍵的值。
#輸出結(jié)果為:[{'age': 1, 'name': 'jim'}, {'age': 5, 'name': 'bell'}, {'age': 10, 'name': 'jan'}, {'age': 20, 'name': 'sunny'}]
print sorted(dic,key=lambda arg:arg.get('name'),reverse=False) #按照每個字典的name的值進行排序
#輸出結(jié)果為:[{'age': 5, 'name': 'bell'}, {'age': 10, 'name': 'jan'}, {'age': 1, 'name': 'jim'}, {'age': 20, 'name': 'sunny'}]
假如需要排序的數(shù)據(jù)為一個二維的list,即list的每一個元素也是一個list,方法與上面的例子類似:
a=[['100','8','30'],['200','5','50'],['300','1','20']]print sorted(a,key=lambda arg:arg[1]) #按照每個list的第1個元素進行排序
[['300', '1', '20'], ['200', '5', '50'], ['100', '8', '30']]
前面的2個例子中,key參數(shù)的值都是函數(shù)。在sorted函數(shù)中,key參數(shù)后面的函數(shù)的參數(shù)的數(shù)量只能是一個。lambda arg:arg.get('age')是一個lambda匿名函數(shù),它是一個沒有函數(shù)名的單語句函數(shù)。冒號左邊是參數(shù),冒號右邊的返回值,返回值將被用于排序。
sorted函數(shù)python介紹如下
sorted() 作為?Python?內(nèi)置函數(shù)之一,其功能是對序列(列表、元組、字典、集合、還包括字符串)進行排序。
sorted() 函數(shù)的基本語法格式如下
list = sorted(iterable, key=None, reverse=False)
其中,iterable 表示指定的序列,key 參數(shù)可以自定義排序規(guī)則;reverse 參數(shù)指定以升序(False,默認(rèn))還是降序(True)進行排序。sorted() 函數(shù)會返回一個排好序的列表。
注意,key 參數(shù)和 reverse 參數(shù)是可選參數(shù),即可以使用,也可以忽略。
演示sorted()函數(shù)的基本代碼用法:
#對列表進行排序
a = [5,3,4,2,1]
print(sorted(a))
#對元組進行排序
a = (5,4,3,1,2)
print(sorted(a))
#字典默認(rèn)按照key進行排序
a = {4:1,\
5:2,\
3:3,\
2:6,\
1:8}
print(sorted(a.items()))
#對集合進行排序
a = {1,5,3,2,4}
print(sorted(a))
#對字符串進行排序
a = "51423"
print(sorted(a))
當(dāng)前標(biāo)題:python內(nèi)置函數(shù)排序 python編寫自定義排序函數(shù)
新聞來源:http://jinyejixie.com/article38/doddopp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計、網(wǎng)站設(shè)計公司、、網(wǎng)頁設(shè)計公司、域名注冊、靜態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)