在Python中进行不同级别的排序
我正在尝试对元组列表进行排序,如下所示:在Python中进行不同级别的排序,python,list,sorting,Python,List,Sorting,我正在尝试对元组列表进行排序,如下所示: [('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])与Apple,Banan
[('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]
)与Apple
,Banana
和菠萝
)匹配,则列表应该根据tuple[0]
升序进行进一步排序
我试过可能的方法-
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的知识,从而寻求此类解决方案。让您的键返回一个数值为负数的元组,然后返回字符串。通过求反,数字将按降序排序,而字符串则按升序排序:
top_n.sort(key=lambda t: (-t[1], t[0]))
是的,这是一个小技巧,但在任何需要按两个相反方向的标准排序的地方都可以使用,其中一个标准是数字
演示:
在您的例子中,Martijn Pieters解决方案可能是最好的,但我正在考虑如果您需要对任意数量的参数执行此操作,并且需要执行一些升序和降序操作,您会怎么做 这种方法创建一个函数来动态生成排序索引。使用要排序的元组列表和包含索引的列表调用getsortfunction,如果它们应该以相反的顺序(例如
(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首先按顺序构建唯一值的嵌套列表,并返回一个函数,该函数将要排序的每个值映射到一个数值元组,给出排序值列表中的索引
这种方法的最大优点是,您可以在运行时确定排序标准(例如,从用户请求)。此解决方案的唯一问题是,求反仅适用于整数。我没有更好的建议,我的解决方案是一样的。如果两个元组参数都是字符串呢?@Arman:进一步的黑客攻击:将字符串转换成一个否定整数序列(
[-chr(c)表示字符串中的c]
)。@Arman:或者按照OP所做的做;先按次要标准按一个方向排序,然后再按主要标准排序。@MartijnPieters太好了,谢谢!实际上,您可以简单地执行:top\n.sort();顶部排序(key=itemgetter(1),reverse=True)
。因为reverse=False
是默认值。另外,使用itemgetter(0)
也没有太大意义,因为序列已经按照第一个元素进行了排序,所以您可以简单地避免使用键
@Bakuriu:是的!对。谢谢你的建议。这是我一直在尝试的解决方案,但我想我可能做得太多了(Python的新手),所以停止了。虽然有点难看,但我相信这是有效的解决办法。非常感谢。
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)]))