讀古今文學網 > 父與子的編程之旅:與小卡特一起學Python > 12.13 列表排序 >

12.13 列表排序

列表是一種有順序(ordered)的集合 。這說明列表中的元素有某種順序,每個元素都有一個位置,也就是它的索引。一旦以某種順序將元素放在列表中,它們就會保持這種順序,除非用 insertappendremovepop 改變列表。不過這個順序可能不是你真正想要的順序。你可能希望列表在使用前已經排序。

要對列表排序,可以使用 sort 方法。

>>> letters = [\'d\', \'a\', \'e\', \'c\', \'b\']>>> print letters[\'d\', \'a\', \'e\', \'c\', \'b\']>>> letters.sort>>> print letters[\'a\', \'b\', \'c\', \'d\', \'e\']  

sort 會自動按字母順序對字符串從小到大排序,如果是數字,就會按數字順序從小到大排序。

有一點很重要,你要知道 sort 會在原地修改列表。這說明它會改變你提供的原始列表,而不是創建一個新的有序列表。所以,你不能這樣做:

>>> print letters.sort  

如果這樣做,會得到「None」。必須分兩步來完成,就像這樣:

>>> letters.sort>>> print letters  

按逆序排序

讓一個列表按逆序排序有兩種方法。一種方法是先按正常方式對列表排序,然後對這個有序列表完成逆置(reverse),如下:

>>> letters = [\'d\', \'a\', \'e\', \'c\', \'b\']>>> letters.sort>>> print letters[\'a\', \'b\', \'c\', \'d\', \'e\']>>> letters.reverse>>> print letters[\'e\', \'d\', \'c\', \'b\', \'a\']  

在這裡我們看到一個新的列表方法 reverse,它會把列表中元素的順序倒過來。

另一種方法是向 sort 增加了一個參數,直接讓它按降序排序(從大到小):

>>> letters = [\'d\', \'a\', \'e\', \'c\', \'b\']>>> letters.sort (reverse = True)>>> print letters[\'e\', \'d\', \'c\', \'b\', \'a\']  

這個參數名為 reverse,它會按照你的意願,將列表按逆序排序。

要記住,我們剛才討論的所有排序和逆置都會對原來的列表做出修改。這說明,你原來的列表已經沒有了。如果希望保留原來的順序,而對列表的副本進行排序,可以使用分片記法建立副本,也就是與原列表相等的另一個列表(有關的內容已經在這一章前面討論過):

>>> original_list = [\'Tom\', \'James\', \'Sarah\', \'Fred\']>>> new_list = original_list[:]>>> new_list.sort>>> print original_list[\'Tom\', \'James\', \'Sarah\', \'Fred\']>>> print new_list[\'Fred\', \'James\', \'Sarah\', \'Tom\']  

卡特,很高興你問這個問題。如果你還記得很早很早以前我們剛開始談到名字和變量時(第 2 章 ),曾經說過,完成 name1 = name2 之類的操作時,就是為同一個東西建立一個新的名字。應該還記得這個圖:

所以為一個東西指定另一個名字時,只是向同一個東西增加一個新的標籤。在卡特的這個例子中,new_listoriginal_list 都表示同一個列表。可以用任何一個名字來改變列表(例如,可以對它排序)。不過,這裡仍然只有一個列表,就如:

我們對 new 完成排序,但是 original 也同樣得到排序,因為 neworiginal 只是同一個列表的兩個不同名字。這裡並沒有兩個不同的列表。

當然,也可以把 new 標籤移到一個全新的列表上,就像這樣:

第 2 章對字符串和數就是這樣做的。

這說明,如果你確實想建立一個列表的副本,就要另想辦法,而不能只是用 new = original。要達到這個目的,最容易的方法是使用分片記法,就像前面所做的:new = original[:]。這表示「複製列表中的所有內容,從第一個元素到最後一個元素」。這樣就可以得到:

這裡有兩個不同的列表。我們建立了原列表的副本,命名為 new。現在如果對一個列表排序,另一個列表將不會同時排序。

另一種排序方法——sorted

還有一種方法可以得到一個列表的有序副本而不會影響原列表的順序。Python 提供了一個名為 sorted 的函數可以完成這個功能。它的工作如下:

>>> original = [5, 2, 3, 1, 4]>>> newer = sorted(original)>>> print original[5, 2, 3, 1, 4]>>> print newer[1, 2, 3, 4, 5] 

sorted 函數提供了原列表的一個有序副本。