1.先說一下iterable,中文意思是迭代器。
Python的幫助文檔中對iterable的解釋是:iteralbe指的是能夠一次返回它的一個成員的對象。iterable主要包括3類:
第一類是所有的序列類型,比如list(列表)、str(字符串)、tuple(元組)。
第二類是一些非序列類型,比如dict(字典)、file(文件)。
第三類是你定義的任何包含__iter__()或__getitem__()方法的類的對象。
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)]
