2016-01-14 32 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]')。 –