2016-01-14 33 views
9
各級

我試圖理清這樣的元組的列表:排序在Python中

[('Pineapple', 1), ('Orange', 3), ('Banana', 1), ('Apple', 1), ('Cherry', 2)] 

排序列表應該是:

[('Orange', 3), ('Cherry', 2), ('Apple', 1), ('Banana', 1), ('Pineapple', 1)] 

所以,在這裏一日清單應進行排序基於tuple[1]降序排列,那麼如果tuple值(tuple[1])的比賽像AppleBanana & Pineapple - 名單應進一步排序基於tuple[0]在ascendi訂單。

我曾嘗試可能ways-

top_n.sort(key = operator.itemgetter(1, 0), reverse = True) 
# Output: [(Orange, 3), (Cherry, 2), (Pineapple, 1), (Banana, 1), (Apple, 1)] 

"reverse = True",菠蘿,香蕉,然後...

我終於想出了一個辦法:

top_n.sort(key = operator.itemgetter(0), reverse = False) 
top_n.sort(key = operator.itemgetter(1), reverse = True) 

有沒有更好的方式像我的第一種方法一樣得到解決方案。我正在努力探索更多關於Python的知識,從而尋求這樣的解決方案。

+0

其實你可以簡單地做:'top_n.sort(); top_n.sort(key = itemgetter(1),reverse = True)'。因爲'reverse = False'是默認值。另外使用'itemgetter(0)'並沒有太大意義,因爲序列已經被第一個元素排序了,所以你可以簡單地避免使用'key'。 – Bakuriu

+0

@Bakuriu:是的!真正。感謝您的建議。 –

回答

2

在你的情況,馬亭Pieters的解決方案可能是最好的,但我正在考慮,如果你需要的任何數量的參數,這樣做你會做什麼,做一些必要的上升和下降。

該方法創建一個函數來即時生成排序索引。使用要排序的元組列表調用getsort函數,並且包含索引的列表以及它們是否應該以相反順序(例如(2,True)表示反向順序的第二個索引)返回一個爲對象創建排序索引的函數。這是相當醜陋,但多才多藝。

def getsortfunction(values,indices): 
    sorts = [sorted(list(set(x[indices[i][0]] for x in values)),reverse=indices[i][1]) for i in range(len(indices))] 
    def sortfunction(y): 
     return tuple(sorts[i].index(y[indices[i][0]]) for i in range(len(indices))) 
    return sortfunction 

實例

a = [('Pineapple',1),('Orange',3),('Banana',1),('Apple',1),('Cherry',2)] 
# sort a by index 1 first (in reverse order) and then by index 0 in non-reverse order 
b = sorted(a,key=getsortfunction(a,[(1,True),(0,False)])) # gives desired list 

隨着附加標準

c = [('Pineapple',1,'Hawaii'),('Orange',3,'Florida'),('Banana',1,'Hawaii'),('Apple',1,'Washington'),('Cherry',2,'Washington')] 
# sort first by number (in reverse order) then by state, and finally by fruit 
d = sorted(c,key=getsortfunction(c,[(1,True),(2,False),(0,False)])) 

# sort c first by number (in reverse order), then by fruit, ignoring state 
e = sorted(c,key=getsortfunction(c,[(1,True),(0,False)])) 

的getsortfunction首先建立唯一值的嵌套列表中順序,並返回其中每個值映射到被分揀到一個功能在排序後的值列表中給出其索引的數字元組。

這樣做的最大優點是可以在運行時確定排序標準(例如,根據用戶請求)。

+0

這就是我正在嘗試的那種解決方案,但我想也許我正在過度使用它(Python新手)並停止了它。雖然這很難看,但我相信這是有效的解決方案。謝謝! –

13

讓你的密鑰返回一個數字值爲的元組否則爲,然後是字符串。通過否定,您的號碼將在降序排序,而字符串按升序排序:

top_n.sort(key=lambda t: (-t[1], t[0])) 

是的,這是一個黑客攻擊的一位,但工程你需要的地方在對面兩個標準進行排序方向,其中一個標準是數字。

演示:

>>> top_n = [('Pineapple', 1), ('Orange', 3), ('Banana', 1), ('Apple', 1), ('Cherry', 2)] 
>>> sorted(top_n, key=lambda t: (-t[1], t[0])) 
[('Orange', 3), ('Cherry', 2), ('Apple', 1), ('Banana', 1), ('Pineapple', 1)] 
+1

此解決方案的唯一問題是否定僅適用於整數。我不能提出任何更好的建議,我的解決方案是一樣的。 – fodma1

+0

如果兩個元組參數都是字符串呢? – Arman

+3

@Arman:進一步黑客:將字符串轉換爲否定整數序列('[-chr(c)for c in string]')。 –