Python 排序---sort與sorted學習

當咱們從數據庫中獲取一寫數據後,通常對於列表的排序是常常會遇到的問題,今天總結一下python對於列表list排序的經常使用方法:python

第一種:內建方法sort()

能夠直接對列表進行排序git

用法:數據庫

list.sort(func=None, key=None, reverse=False(or True))函數

  • 對於reverse這個bool類型參數,當reverse=False時:爲正向排序;當reverse=True時:爲方向排序。默認爲False。
  • 執行完後會改變原來的list,若是你不須要原來的list,這種效率稍微高點
  • 爲了不混亂,其會返回none

例如:spa

>>> list = [2,8,4,6,9,1,3]
>>> list.sort()
>>> list
[1, 2, 3, 4, 6, 8, 9]

 

第二種:內建函數sorted()

這個和第一種的差異之處在於:.net

  • sorted()不會改變原來的list,而是會返回一個新的已經排序好的list
  • list.sort()方法僅僅被list所定義,sorted()可用於任何一個可迭代對象

用法:code

sorted(list)對象

  • 該函數也含有reverse這個bool類型的參數,當reverse=False時:爲正向排序(從小到大);當reverse=True時:爲反向排序(從大到小)。固然默認爲False。
  • 執行完後會有返回一個新排序好的list

例如:blog

>>> list = [2,8,4,1,5,7,3]
>>> other = sorted(list)
>>> other
[1, 2, 3, 4, 5, 7, 8]

 

擴展用法:

1.Key Function:

從Python2.4開始,list.sort() 和 sorted() 都增長了一個 ‘key’ 參數用來在進行比較以前指定每一個列表元素上要調用的函數。排序

例如:

區分大小寫的字符串比較排序:

>>> sorted("This is a test string from Andrew".split(), key=str.lower)
['a', 'Andrew', 'from', 'is', 'string', 'test', 'This']

key應該是一個函數,其接收一個參數,而且返回一個用於排序依據的key。其執行效率很高,由於對於輸入記錄key function可以準確的被調用。

對於複雜的對象,使用對象的下標做爲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)]

使用對象的屬性進行操做:

例如:

>>> 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)]

 

前段時間遇到這種狀況,那就是列表裏面每個元素不止一個元素(好比:列表裏面,元素爲元祖類型),咱們除了想對第一個關鍵字排序以外,還想在第一次的基礎上面根據第二個關鍵字進行排序,正好是用到的這種方法:

簡化出一個例子:

咱們想先排序列表list中元素的第一個關鍵字,而後在第一個元素的基礎上排序按第二個關鍵字進行排序,看結果:

>>> list = [('d',3),('a',5),('d',1),('c',2),('d',2)]
>>> print sorted(list, key = lambda x:(x[0],x[1]))
[('a', 5), ('c', 2), ('d', 1), ('d', 2), ('d', 3)]

 

2.Operator Module Functions

這個操做模塊有:

  • operator.itemgetter()   ----- 經過下標
  • operator.attrgetter()   ----- 經過參數
  • operator.methodcaller() -----python 2.5 被引入,下文詳細介紹

使用這幾個函數,對於上面 Key Function 的例子處理起來將會更加的簡便和快速

先一塊介紹 operator.itemgetter() 和 operator.attrgetter() 這倆個,會更加容易理解:

例如:

>>> 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)]

這個操做模塊也容許多層次的進行排序,例如能夠先排序 「成績grand」 再排序 「年齡age」

例如:

>>> 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)]

如今回過頭來發現,上面在前幾天遇到的問題,能夠用這個operator.itemgetter進行解決:

>>> list = [('d',3),('a',5),('d',1),('c',2),('d',2)]
>>> from operator import itemgetter
>>> sorted(list, key=itemgetter(0,1))
[('a', 5), ('c', 2), ('d', 1), ('d', 2), ('d', 3)]

可是仍是推薦 1.key function 中的方法,由於爲了這一個排序而引入一個庫文件,相對來講得不償失。

下面介紹operator.methodcaller() 函數:

這個函數是對某個對象的使用固定參數進行排序,例如:str.count() 函數能夠計算每一個字符串對象中含有某個參數的個數,那運用這個函數我就能夠經過 str.count() 計算出某個字符的個數從而來肯定排序的優先級:

>>> from operator import methodcaller
>>> messages = ['critical!!!', 'hurry!', 'standby', 'immediate!!']
>>> sorted(messages, key=methodcaller('count', '!'))
['standby', 'hurry!', 'immediate!!', 'critical!!!']

 

3.注意事項:

排序的穩定性:

從python2.2版本開始,排序是保障穩定性的,意思就是說,當複雜的排序中,對象有相同的key的時候,會保持原有的順序不變:

例如:

>>> data = [('red', 1), ('blue', 1), ('red', 2), ('blue', 2)]
>>> sorted(data, key=itemgetter(0))
[('blue', 1), ('blue', 2), ('red', 1), ('red', 2)]

能夠看到,('blue',1) 和 (‘blue’,2) 的順序仍是維持原來那樣不改變。

複雜排序:

這個排序的屬性可讓你在一系列的步驟中構建複雜的排序操做。例如上面的例子,排序中,我想先經過 「成績grand」 進行降序操做,而後再經過「年齡age」 進行升序操做,首先先經過 「年齡age」 排序,而後再經過 「成績grand」 排序:

>>> s = sorted(student_objects, key=attrgetter('age'))     # sort on secondary key
>>> sorted(s, key=attrgetter('grade'), reverse=True)       # now sort on primary key, descending
[('dave', 'B', 10), ('jane', 'B', 12), ('john', 'A', 15)]

 

4.新增的問題:

今天遇到了這麼一個問題,就是遇到一個字符串的處理問題,好比說 f10 得排在 f2 的後面。找到了這麼一種方法,供參考:

參考地址:http://blog.csdn.net/houyj1986/article/details/22966799

#encoding=utf-8  
print '中國'  
#根據字符串中的數字排序,如f10應該在f2後面  
import re  
  
re_digits = re.compile(r'(\d+)')  
  
def emb_numbers(s):  
    pieces=re_digits.split(s)  
    pieces[1::2]=map(int,pieces[1::2])      
    return pieces  
  
def sort_strings_with_emb_numbers(alist):  
    aux = [(emb_numbers(s),s) for s in alist]  
    aux.sort()  
    return [s for __,s in aux]  
  
def sort_strings_with_emb_numbers2(alist):  
    return sorted(alist, key=emb_numbers)  
  
filelist='file10.txt file2.txt file1.txt'.split()  
  
print filelist  
  
print '--DSU排序'  
print sort_strings_with_emb_numbers(filelist)  
  
print '--內置DSU排序'  
print sort_strings_with_emb_numbers2(filelist)  

打印結果以下:

中國
['file10.txt', 'file2.txt', 'file1.txt']
--DSU排序
['file1.txt', 'file2.txt', 'file10.txt']
--內置DSU排序
['file1.txt', 'file2.txt', 'file10.txt']
相關文章
相關標籤/搜索