Python中sorted()方法的用法
1.先說一下iterable,中文意思是迭代器。
Python的幫助文件中對iterable的解釋是:iteralbe指的是能夠一次返回它的一個成員的物件。iterable主要包括3類:
第一類是所有的序列型別,比如list(列表)、str(字串)、tuple(元組)。
第二類是一些非序列型別,比如dict(字典)、file(檔案)。
第三類是你定義的任何包含__iter__()或__getitem__()方法的類的物件。
2.Python幫助文件中對sorted方法的講解:
sorted(iterable[,cmp,[,key[,reverse=True]]])
作用:Return a new sorted list from the items in iterable.
第一個引數是一個iterable,返回值是一個對iterable中元素進行排序後的列表(list)。
可選的引數有三個,cmp、key和reverse。
1)cmp指定一個定製的比較函式,這個函式接收兩個引數(iterable的元素),如果第一個引數小於第二個引數,返回一個負數;如果第一個引數等於第二個引數,返回零;如果第一個引數大於第二個引數,返回一個正數。預設值為None。
2)key指定一個接收一個引數的函式,這個函式用於從每個元素中提取一個用於比較的關鍵字。預設值為None。
3)reverse是一個布林值。如果設定為True,列表元素將被倒序排列。
通常來說,key和reverse比一個等價的cmp函式處理速度要快。這是因為對於每個列表元素,cmp都會被呼叫多次,而key和reverse只被呼叫一次。
3.具體的用法如下:
1)排序基礎
一個簡單的升序排列很簡單-只需要呼叫sorted()函式即可。 這個函式返回一個新的排序列表。:
>>> sorted([5,2,3,1,4])
[1,2,3,4,5]
你也可以使用list的list.sort()方法。這個方法會修改原始的list(返回值為None)。通常這個方法不如sorted()方便-如果你不需要原始的list,list.sort()方法效率會稍微高一些。
>>> a=[5,2,3,1,4]
>>> a.sort()
>>> a
[1,2,3,4,5]
另一個區別在於list.sort()方法只為list定義。而sorted()函式可以接收任何的iterable。
>>> sorted({1: 'D', 2: 'B', 3: 'B', 4: 'E', 5: 'A'}) [1, 2, 3, 4, 5]
2)Key Functions(關鍵字函式)
從Python2.4開始,list.sort()和sorted()方法都新增了一個key引數來說明一個函式,這個函式在做比較之前會對list中的每個元素進行呼叫。
例如,這裡是一個大小寫不敏感的字串比較:
>>> sorted("This is a test string from Andrew".split(), key=str.lower) ['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']
key的值應該是一個函式,這個函式接收一個引數並且返回一個用於比較的關鍵字。這種技術比較快,原因在於對每個輸入記錄,這個函式只會被呼叫一次。
對複雜物件的比較通常是使用物件的切片作為關鍵字。例如:
>>> student_tuples = [ ('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10), ]
>>> sorted(student_tuples, key=lambda student: student[2]) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
同樣的技術適用於有named屬性的物件。例如:
>>> class Student: def init(self, name, grade, age):
self.name = name
self.grade = grade
self.age = age
def repr(self):
return repr((self.name, self.grade, self.age))
>>> student_objects = [Student('john', 'A', 15),Student('jane', 'B', 12),Student('dave', 'B', 10), ]
>>> sorted(student_objects, key=lambda student: student.age) # sort by age [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
3)Operator Module Functions (Operator模組中的函式)
上面的key-function模式很常見,因此Python提供了方便的函式使得祖先函式更簡單和快捷。operator module有itemgetter,attrgetter,以及從Python2.6開始的methodcaller函式。
使用這些函式,上面的例子會變得更簡單和快捷:
>>> from operator import itemgetter, attrgetter
>>> sorted(student_tuples, key=itemgetter(2)) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
>>> sorted(student_objects, key=attrgetter('age')) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]
operator模組支援多級排序。例如先按成績排序,再按年齡排序:
>>> sorted(student_tuples, key=itemgetter(1,2)) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
>>> sorted(student_objects, key=attrgetter('grade', 'age')) [('john', 'A', 15), ('dave', 'B', 10), ('jane', 'B', 12)]
4)升序和降序
list.sort()和sorted()都接收一個reverse引數。它是用於降序排序的標誌。例如,為了獲得學生年齡的降序排序:
>>> sorted(student_tuples, key=itemgetter(2), reverse=True) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)] >>> sorted(student_objects, key=attrgetter('age'), reverse=True) [('john', 'A', 15), ('jane', 'B', 12), ('dave', 'B', 10)]
5)排序穩定性和複雜的排序 從Python2.2開始,排序都保證是穩定的。
意思是當多個記錄有相同的關鍵字時,它們原始的排序保留。
>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=itemgetter(0)) [('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]
注意到兩個'blue'的記錄保留了它們原始的順序,因此('blue',1)保證在('blue',2)之前。 這個好的特效能讓你建立複雜的排序。例如,將學生記錄按成績降序排序、按年兩升序排列。先按年齡排序,再按成績排序。
>>> s=sorted(student_object,key=attrgettter('age')) # sort on secondary key
>>> sorted(s,key=attrgetter('grade'),reverse=True) [('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]