在Python中以各种级别排序

Pru*_*oru 9 python sorting list

我试图对这些元组列表进行排序:

[('Pineapple', 1), ('Orange', 3), ('Banana', 1), ('Apple', 1), ('Cherry', 2)]
Run Code Online (Sandbox Code Playgroud)

排序列表应为:

[('Orange', 3), ('Cherry', 2), ('Apple', 1), ('Banana', 1), ('Pineapple', 1)]
Run Code Online (Sandbox Code Playgroud)

所以,这里第一个列表应该按tuple[1]降序排序,然后如果tuplevalues(tuple[1])匹配Apple,那么Banana&Pineapple- list应该按tuple[0]升序进一步排序.

我尝试了可能的方法 -

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

"reverse = True",菠萝,香蕉,......

我最终不得不想出一个解决方案:

top_n.sort(key = operator.itemgetter(0), reverse = False)
top_n.sort(key = operator.itemgetter(1), reverse = True)
Run Code Online (Sandbox Code Playgroud)

有没有比我的第一种方法更好的方法来获得解决方案.我正在尝试更多地探索Python,从而寻求这样的解决方案.

Mar*_*ers 13

让你的密钥返回一个否定数值的元组,然后是字符串.通过否定,您的数字将按降序排序,而字符串按升序排序:

top_n.sort(key=lambda t: (-t[1], t[0]))
Run Code Online (Sandbox Code Playgroud)

是的,这有点像黑客攻击,但可以在任何需要按相反方向按两个标准排序的地方工作,其中一个标准是数字.

演示:

>>> 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)]
Run Code Online (Sandbox Code Playgroud)

  • @Arman:进一步黑客攻击:将字符串转换为一系列否定整数(`[字符串中的c为[-chr(c)]`). (3认同)
  • @Arman:或做OP所做的事; 首先按一个方向的次要标准排序,然后再按主要标准排序*. (2认同)

Mat*_*hew 2

就您而言,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
Run Code Online (Sandbox Code Playgroud)

例子

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
Run Code Online (Sandbox Code Playgroud)

具有附加条件

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)]))
Run Code Online (Sandbox Code Playgroud)

getsort 函数首先按顺序构建唯一值的嵌套列表,并返回一个函数,该函数将要排序的每个值映射到一个数字元组,并给出其在排序值列表中的索引。

这样做的最大优点是您可以在运行时确定排序标准(例如根据用户请求)。