排序算法
排序也是在程序中經(jīng)常用到的算法婆翔。無論使用冒泡排序還是快速排序,排序的核心是比較兩個元素的大小侨舆。如果是數(shù)字雁竞,我們可以直接比較佳头,但如果是字符串或者兩個dict呢氮惯?直接比較數(shù)學(xué)上的大小是沒有意義的襟士,因此览爵,比較的過程必須通過函數(shù)抽象出來慷嗜。通常規(guī)定淀弹,對于兩個元素x和y,如果認為x < y庆械,則返回-1薇溃,如果認為x == y,則返回0缭乘,如果認為x > y沐序,則返回1,這樣堕绩,排序算法就不用關(guān)心具體的比較過程策幼,而是根據(jù)比較結(jié)果直接排序。
Python內(nèi)置的sorted()函數(shù)就可以對list進行排序:
>>> sorted([36, 5, -12, 9, -21])
[-21, -12, 5, 9, 36]
此外奴紧,sorted()函數(shù)也是一個高階函數(shù)特姐,它還可以接收一個key函數(shù)來實現(xiàn)自定義的排序,例如按絕對值大小排序:
>>> sorted([36, 5, -12, 9, -21], key=abs)
[5, 9, -12, -21, 36]
key指定的函數(shù)將作用于list的每一個元素上黍氮,并根據(jù)key函數(shù)返回的結(jié)果進行排序唐含。對比原始的list和經(jīng)過key=abs處理過的list:
key 也可以指定根據(jù)列表里面,元組中的某個因素來排序(見習(xí)題)
我們再看一個字符串排序的例子:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'])
['Credit', 'Zoo', 'about', 'bob']
默認情況下沫浆,對字符串排序捷枯,是按照ASCII的大小比較的,由于'Z' < 'a',結(jié)果,大寫字母Z會排在小寫字母a的前面砚哆。
現(xiàn)在惊来,我們提出排序應(yīng)該忽略大小寫攀痊,按照字母序排序桐腌。要實現(xiàn)這個算法,不必對現(xiàn)有代碼大加改動苟径,只要我們能用一個key函數(shù)把字符串映射為忽略大小寫排序即可哩掺。忽略大小寫來比較兩個字符串,實際上就是先把字符串都變成大寫(或者都變成小寫)涩笤,再比較。
這樣盒件,我們給sorted傳入key函數(shù)蹬碧,即可實現(xiàn)忽略大小寫的排序:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower)
['about', 'bob', 'Credit', 'Zoo']
要進行反向排序,不必改動key函數(shù)炒刁,可以傳入第三個參數(shù)r
everse=True:
>>> sorted(['bob', 'about', 'Zoo', 'Credit'], key=str.lower, reverse=True)
['Zoo', 'Credit', 'bob', 'about']
從上述例子可以看出恩沽,高階函數(shù)的抽象能力是非常強大的,而且翔始,核心代碼可以保持得非常簡潔罗心。
小結(jié)
sorted()也是一個高階函數(shù)。用sorted()排序的關(guān)鍵在于實現(xiàn)一個映射函數(shù)城瞎。
練習(xí)
假設(shè)我們用一組tuple表示學(xué)生名字和成績:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)]
請用sorted()對上述列表分別按名字排序:
https://github.com/miaozaiye/python-learning/blob/master/923.py