《Python数据科学指南》——1.23 采用键排序
本節(jié)書摘來自異步社區(qū)《Python數(shù)據(jù)科學(xué)指南》一書中的第1章,第1.23節(jié),作者[印度] Gopi Subramanian ,方延風(fēng) 劉丹 譯,更多章節(jié)內(nèi)容可以訪問云棲社區(qū)“異步社區(qū)”公眾號查看。
1.23 采用鍵排序
到目前為止,我們的示例都是采用元素對列表或其他序列進行排序,現(xiàn)在我們來試試對它們采用鍵排序。在前面的那些示例中,元素即是鍵。而在真實場景中,記錄的復(fù)雜度要高得多,一條記錄包含了多個列,我們有時需要對其中一個或多個列進行排序。我們通過對一個元組的列表進行排序來闡述,并將之推廣到其他的序列類型。
1.23.1 準備工作
本示例中,一個單獨的元組表示一個人的個人記錄,包括名字、ID、年齡等。我們來編寫一段對不同的域進行排序的代碼。
1.23.2 操作方法
我們使用列表和元組來編寫一個記錄類的結(jié)構(gòu),并使用這些數(shù)據(jù)演示如何采用鍵進行排序。
# 1.首先創(chuàng)建一個元組組成的列表用來測試排序 employee_records = [ ('joe',1,53),('beck',2,26), \('ele',6,32),('neo',3,45), \('christ',5,33),('trinity',4,29), \]# 2.使用雇員名字進行排序 print sorted(employee_records,key=lambda emp : emp[0]) """ 輸出結(jié)果如下。 [('beck', 2, 26), ('christ', 5, 33), ('ele', 6, 32), ('joe', 1, 53),\ ('neo', 3, 45), ('trinity', 4, 29)] """ # 3. 使用雇員ID進行排序 print sorted(employee_records,key=lambda emp : emp[1]) """ 輸出結(jié)果如下。 [('joe', 1, 53), ('beck', 2, 26), ('neo', 3, 45), ('trinity', 4, 29),\ ('christ', 5, 33), ('ele', 6, 32)] """ # 4. 使用雇員年齡進行排序 print sorted(employee_records,key=lambda emp : emp[2]) """輸出結(jié)果如下。
[('beck', 2, 26), ('trinity', 4, 29), ('ele', 6, 32), ('christ', 5,\ 33), ('neo', 3, 45), ('joe', 1, 53)] """1.23.3 工作原理
在我們的示例中,每條記錄有3個域:姓名、ID和年齡。我們使用lambda函數(shù)來將我們需要排序的鍵進行傳遞。在第2步中,我們將姓名作為鍵來進行排序。類似地,在第2步和第3步中,都分別采用了ID和年齡作為鍵,這些不同步驟里的不同輸出結(jié)果顯示了我們想要的排序結(jié)果。
1.23.4 更多內(nèi)容
由于鍵排序十分重要,Python提供了快捷的函數(shù)來訪問鍵,而不用自己寫lambda函數(shù)。operator模塊中提供了itemgetter、attrgetter和methodcaller等幾個函數(shù)。前面排序示例我們可以使用itemgetter來重寫,代碼如下。
from operator import itemgetter employee_records = [ ('joe',1,53),('beck',2,26), \('ele',6,32),('neo',3,45), \('christ',5,33),('trinity',4,29), \] print sorted(employee_records,key=itemgetter(0)) """ [('beck', 2, 26), ('christ', 5, 33), ('ele', 6, 32), ('joe', 1, 53),\ ('neo', 3, 45), ('trinity', 4, 29)] """ print sorted(employee_records,key=itemgetter(1)) """ [('joe', 1, 53), ('beck', 2, 26), ('neo', 3, 45), ('trinity', 4, 29),\ ('christ', 5, 33), ('ele', 6, 32)] """ print sorted(employee_records,key=itemgetter(2)) """ [('beck', 2, 26), ('trinity', 4, 29), ('ele', 6, 32), ('christ', 5,\ 33), ('neo', 3, 45), ('joe', 1, 53)] """請注意我們不再使用lambda函數(shù),而是采用itemgetter來指定我們用來排序的鍵。如果需要多級排序,itemgetter可以接收多個用來排序的域。例如,我們先對名字,再對年齡進行排序,那代碼如下。
>>> sorted(employee_records,key=itemgetter(0,1)) [('beck', 2, 26), ('christ', 5, 33), ('ele', 6, 32), ('joe', 1, 53), ('neo', 3, 45), ('trinity', 4, 29)]如果可迭代對象里的元素是類對象,則可以用attrgetter和methodcaller輕松搞定。請看如下示例。
# 將雇員記錄封裝為類對象 class employee(object):def __init__(self,name,id,age):self.name = nameself.id = idself.age = agedef pretty_print(self):print self.name,self.id,self.age# 將這些類對象填入列表里 employee_records = [] emp1 = employee('joe',1,53) emp2 = employee('beck',2,26) emp3 = employee('ele',6,32)employee_records.append(emp1) employee_records.append(emp2) employee_records.append(emp3)# 打印輸出記錄 for emp in employee_records:emp.pretty_print()from operator import attrgetter employee_records_sorted = sorted(employee_ records,key=attrgetter('age')) # 打印輸出排序后的記錄 for emp in employee_records_sorted:emp.pretty_print()構(gòu)造器使用name、age和ID等3個變量對類進行初始化,類還擁有一個pretty_print方法來輸出類對象的各個值。
接著,把這些類對象填入一個列表。
employee_records = [] emp1 = employee('joe',1,53) emp2 = employee('beck',2,26) emp3 = employee('ele',6,32) employee_records.append(emp1) employee_records.append(emp2) employee_records.append(emp3)現(xiàn)在,我們有一個雇員對象的列表,每個對象中有3個變量:name、ID和age。我們將列表打印輸出來觀察其順序。
joe 1 53 beck 2 26 ele 6 32如你所見,你的輸入順序被保留下來了。現(xiàn)在,我們使用attrgetter根據(jù)age域來對列表進行排序。
employee_records_sorted = sorted(employee_ records,key=attrgetter('age'))打印輸出排序后的列表,結(jié)果如下。
beck 2 26 ele 6 32 joe 1 53記錄已經(jīng)被按照年齡進行了排序。
如果想用類里的某個方法來決定排序方式,我們得使用methodcaller。我們設(shè)計一個演示場景:添加一個隨機方法,將年齡除以ID。
class employee(object):def __init__(self,name,id,age):self.name = nameself.id = idself.age = agedef pretty_print(self):print self.name,self.id,self.agedef random_method(self):return self.age / self.id# 填充數(shù)據(jù) employee_records = [] emp1 = employee('joe',1,53) emp2 = employee('beck',2,26) emp3 = employee('ele',6,32)employee_records.append(emp1) employee_records.append(emp2) employee_records.append(emp3)from operator import methodcaller employee_records_sorted = sorted(employee_records,key=methodcaller('ra\ ndom_method')) for emp in employee_records_sorted:emp.pretty_print()現(xiàn)在我們調(diào)用這個方法來進行排序。
sorted(employee_records,key=methodcaller('random_method'))
打印輸出排序后的列表,結(jié)果如下。
ele 6 32 beck 2 26 joe 1 53總結(jié)
以上是生活随笔為你收集整理的《Python数据科学指南》——1.23 采用键排序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《Splunk智能运维实战》——3.6
- 下一篇: Clinicast让癌症治疗不那么昂贵