Python中sort与sorted函数
python中列表的內置函數sort()可以對列表中的元素進行排序,而全局性的sorted()函數則對所有可迭代的序列都是適用的;
并且sort()函數是內置函數,會改變當前對象,而sorted()函數只會返回一個排序后的當前對象的副本,而不會改變當前對象。
sort
原型:sort(fun,key,reverse=False)
參數fun是表明此sort函數是基于何種算法進行排序的,一般默認情況下python中用的是歸并排序,并且一般情況下我們是不會重寫此參數的,所以基本可以忽略;
參數key用來指定一個函數,此函數在每次元素比較時被調用,此函數代表排序的規則,也就是你按照什么規則對你的序列進行排序;
參數reverse是用來表明是否逆序,默認的False情況下是按照升序的規則進行排序的,當reverse=True時,便會按照降序進行排序。
#coding:utf-8 from operator import attrgetter,itemgetter list1 = [(2,'huan',23),(12,'the',14),(23,'liu',90)] #使用默認參數進行排序,即按照元組中第一個元素進行排序 list1.sort() print list1 #輸出結果為[(2, 'huan', 23), (12, 'the', 14), (23, 'liu', 90)] #使用匿名表達式重寫key所代表的函數,按照元組的第二個元素進行排序 list1.sort(key=lambda x:(x[1])) print list1 #[(2, 'huan', 23), (23, 'liu', 90), (12, 'the', 14)] #使用匿名表達式重寫key所代表的函數,按照元組的第三個元素進行排序 list1.sort(key=lambda x:(x[2])) print list1 #[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)] #使用匿名函數重寫key所代表的函數,先按照元組中下標為2的進行排序, # 對于下標2處元素相同的,則按下標為0處的元素進行排序 list1.sort(key=lambda x:(x[2],x[0])) print list1 #[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)] #使用operator模塊中的itemgetter函數進行重寫key所代表的函數,按照下標為1處的元素進行排序 list1.sort(key=itemgetter(1)) print list1 #[(2, 'huan', 23), (23, 'liu', 90), (12, 'the', 14)] #使用operator模塊中的itemgetter函數進行重寫key所代表的函數,按照下標為2處的元素進行排序 list1.sort(key=itemgetter(2)) print list1 # [(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)] # 此處可以類比lambda中的排序方法,就不再解釋 list1.sort(key=itemgetter(2,0)) print list1 #[(12, 'the', 14), (2, 'huan', 23), (23, 'liu', 90)]sorted
原型sorted(iterable, cmp=None, key=None, reverse=False)
對于sorted()函數中key的重寫,和sort()函數中是一樣的,所以剛剛對于sort()中講解的方法,都是適用于sorted()函數中
cmp函數:
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' # 排序算法: # 排序也是在程序中經常用到的算法。 # 無論使用冒泡排序還是快速排序,排序的核心是比較兩個元素的大小。 # 如果是數字,我們可以直接比較,但如果是字符串或者兩個dict呢?直接比較數學上的大小是沒有意義的,因此,比較的過程必須通過函數抽象出來。 # 通常規定,對于兩個元素x和y,如果認為x < y,則返回-1,如果認為x == y,則返回0,如果認為x > y,則返回1, # 這樣,排序算法就不用關心具體的比較過程,而是根據比較結果直接排序 # Python內置的sorted()函數就可以對list進行排序: print(sorted([34, 5, 7, 2, 8, 13])) print('-----------------------------------------------------------------------------------') # sorted()函數也是一個高階函數,它還可以接收一個比較函數來實現自定義的排序。 # 比如,如果要倒序排序,我們就可以自定義一個reversed_self函數 # 傳入自定義的比較函數reversed_self,就可以實現倒序排序 def reversed_self(x, y): if x > y: return -1 if x < y: return 1 return 0 res = sorted([34, 5, 7, 2, 8, 13], reversed_self) print(res) print('-----------------------------------------------------------------------------------') # 默認情況下,對字符串排序,是按照ASCII的大小比較的,由于'Z' < 'a',結果,大寫字母Z會排在小寫字母a的前面。 # 現在,我們提出排序應該忽略大小寫,按照字母序排序。要實現這個算法,不必對現有代碼大加改動,只要我們能定義出忽略大小寫的比較算法就可以 # Python upper() 方法將字符串中的小寫字母轉為大寫字母。 def ignore_case(x1, x2): u1 = x1.upper() u2 = x2.upper() if u1 < u2: return -1 if u1 > u2: return 1 return 0 # 忽略大小寫來比較兩個字符串,實際上就是先把字符串都變成大寫(或者都變成小寫),再比較 res1 = sorted(['bob', 'about', 'Zoo', 'Credit'], ignore_case) print(res1)sort與sorted函數比較
sorted() 作用于任意可迭代的對象,而 sort() 一般作用于列 表。
因此下面的例子中針對元組使用 sort() 方法會拋出 AttributeError,而使用 sorted() 函數則 沒有這個問題。
>>> a = (1,2,4,2,3) >>> a.sort() Traceback (most recent call last):File "<stdin>", line 1, in <module> AttributeError: 'tuple' object has no attribute 'sort' >>> sorted(a) [1, 2, 2, 3, 4]當排序對象為列表的時候兩者適合的場景不同。sorted() 函數會返回一個排序后的列表,原有列表保持不 變;而 sort() 函數會直接修改原有列表,函數返回為 None。
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> a=['1',1,'a',3,7,'n'] >>> sorted(a) [1, 3, 7, '1', 'a', 'n'] >>> a ['1', 1, 'a', 3, 7, 'n'] >>> print a.sort() None >>> a [1, 3, 7, '1', 'a', 'n']因此如果實際應用過程中需要保留原有列表,使用 sorted() 函數較為適合,否則可以選 擇 sort() 函數,因為 sort() 函數不需要復制原有列表,消耗的內存較少,效率也較高。
無論是 sort() 還是 sorted() 函數,傳入參數 key 比傳入參數 cmp 效率要高。cmp 傳入 的函數在整個排序過程中會調用多次,函數開銷較大;而 key 針對每個元素僅作一次處理, 因此使用 key 比使用 cmp 效率要高。
sorted的強大功能
對字典進行排序(中根據字典的值進行排序)
>>> phonebook = {'Linda': '7750', 'Bob': '9345', 'Carol': '5834'} >>> from operator import itemgetter >>> sorted_pb = sorted(phonebook.iteritems(),key=itemgetter(1)) >>> print sorted_pb [('Carol', '5834'), ('Linda', '7750'), ('Bob', '9345')]ps: iteritems()方法返回字典的迭代器對象。 operator.itemgetter()函數用于獲取對象的哪些維的數據,參數為一些序號(即需要獲取的數據在對象中的序號)。看例子
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' a = [1,2,3] >>> b=operator.itemgetter(1) //定義函數b,獲取對象的第1個域的值 >>> b(a) >>> b=operator.itemgetter(1,0) //定義函數b,獲取對象的第1個域和第0個的值 >>> b(a) (2, 1)要注意,operator.itemgetter函數獲取的不是值,而是定義了一個函數,通過該函數作用到對象上才能獲取值。
多維list排序
實際情況下也會碰到需要對多個字段進行排序的情況,如根據學生的成績、對應的等級依次排序。當然這在 DB 里面用 SQL 語句很容易做到,但使用多維列表聯合 sorted() 函數也可以輕易達到類似的效果。
>>> from operator import itemgetter >>> gameresult = [['Bob',95.00,'A'],['Alan',86.0,'C'['Mandy',82.5,'A'],['Rob',86,'E']] # 分別表示學生的姓名,成績,等級 >>> sorted(gameresult , key=operator.itemgetter(2, 1)) [['Mandy', 82.5, 'A'], ['Bob', 95.0, 'A'], ['Alan', 86.0, 'C'], ['Rob', 86, 'E']] # 當第二個字段成績相同的時候按照等級從低到高排序字典中混合list排序
如果字典中的 key 或者值為列表,需要對列表中的某一個位置 的元素排序也是可以做到的。看例子:
針對字典 mydict 的 value 結構 [n,m] 中的 m 按照從小到大的順序排列。
>>> mydict = { 'Li' : ['M',7], ... 'Zhang': ['E',2], ... 'Wang' : ['P',3], ... 'Du' : ['C',2], ... 'Ma' : ['C',9], ... 'Zhe' : ['H',7] } >>> >>> from operator import itemgetter >>> sorted(mydict.iteritems(), key=lambda (k,v): operator.itemgetter(1)(v)) [('Zhang', ['E', 2]), ('Du', ['C', 2]), ('Wang', ['P', 3]), ('Li',['M', 7]), ('Zhe', ['H', 7]), ('Ma', ['C', 9])]字典中混合list排序
列表中的每一個元素為字典形式,需要針對字典的多個key 值進行排序也不難實現。
看例子:
針對 list 中的字典元素按照 rating 和 name進行排序的實現方法。
''' 遇到問題沒人解答?小編創建了一個Python學習交流QQ群:857662006 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學習教程和PDF電子書! ''' >>> gameresult = [{ "name":"Bob", "wins":10, "losses":3, "rating":75.00 }, ... { "name":"David", "wins":3, "losses":5, "rating":57.00 }, ... { "name":"Carol", "wins":4, "losses":5, "rating":57.00 }, ... { "name":"Patty", "wins":9, "losses":3, "rating": 71.48 }] >>> from operator import itemgetter >>> sorted(gameresult , key=operator.itemgetter("rating","name")) [ {'wins': 4, 'losses': 5, 'name': 'Carol', 'rating': 57.0}, {'wins': 3, 'losses': 5, 'name': 'David', 'rating': 57.0}, {'wins': 9, 'losses': 3, 'name': 'Patty','rating': 71.48}, {'wins': 10, 'losses': 3, 'name': 'Bob', 'rating': 75.0}]PS python2 與python3區別
sorted(iterable, cmp=None, key=None,reverse=False) ## Python 2.xsorted(iterable, key=None,reverse=False) ## Python 3.x由此可看出,Python3.x取消了 cmp參數, 所以如果想給 sorted()函數傳參的話,就剩下 key,和reverse了。
也就是說我們無法直接傳入多個參數的函數進行排序
如果直接寫的話,會發現
## 報錯信息如下: TypeError: must use keyword argument for key function類型錯誤: 必須使用關鍵字參數。
那么我們該如何解決這個問題呢?
那就是使用functools中的cmp_to_key,即在開頭加上
from functools import cmp_to_key
from functools import cmp_to_key def desc(color1_list,color2_list):if len(color1_list) == 0:return -1else:if len(color2_list) == 0:return 1if color1_list[0] > color2_list[0]:return 1else:return -1 sameList = sorted(sameTypeList,key = cmp_to_key(desc))總結
以上是生活随笔為你收集整理的Python中sort与sorted函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python的22个基本语法
- 下一篇: 10 个平板电脑上的 Python 编辑