【问题标题】:Sorting tuples in python using different orders for different fields [duplicate]使用不同字段的不同顺序对python中的元组进行排序[重复]
【发布时间】:2012-08-16 18:08:16
【问题描述】:

假设我们有一个包含 5 个元组的列表:

(a, b , c, d, e)

让列表为 student_tuples。

我希望对不同字段的列表进行不同的排序。

下面提到的命令

sorted(student_tuples, key=itemgetter(2,4,0,1))

将按所有字段的升序对列表进行排序。

下面提到的命令

sorted(student_tuples, key=itemgetter(2,4,0,1), reverse=true)

将按所有字段的降序对列表进行排序。 我正在寻找的是按不同字段的不同顺序对列表进行排序。 有没有一种简单的方法可以做到这一点。

根据答案,该技术可用于任何语言

谢谢, 预测

【问题讨论】:

  • 你的意思是把每个元组的第n个元素放在一个自己的列表中,然后对该列表进行排序?
  • 不,这不是家庭作业问题。我可以创建单独的列表并以复杂的方式进行。
  • a,b,c,d,e是什么类型的对象...?
  • 对不起,我没有得到你的要求。我有 5 个元组的列表。列表中的每个元素都是 5 个元组。
  • 但是元组里面的元素是什么?

标签: python sorting tuples


【解决方案1】:

如果值是数字,您可以使用lambda 轻松完成此操作:

sorted(student_tuples, key=lambda x: (x[2],x[4],-x[0],x[1]))
                                                #^ This field will be 
                                                #  in descending order 

如果你不能轻易的否定一个lambda函数内部的顺序,就需要依赖python排序的稳定性,再排序几次:

s = sorted(student_tuples, key=itemgetter(1))
s.sort(key=itemgetter(0),reversed=True)
s.sort(key=itemgetter(2,4))

我在this answer中更深入地解释它。

证明我上面的答案完成了同样的事情(使用数字输入):

import random
def rand_tuple():
    """ Return a random 5-tuple """
    return tuple( random.random() for _ in range(5) )

#100 random 5-tuples
lst = [ rand_tuple() for _ in range(100) ] 

#sort the list using method 1
sorted_lst = sorted(lst, key = lambda x: (x[2],x[4],-x[0],x[1])) 

#sort the list in place using method 2
lst.sort(key = itemgetter(1))  #<- Rightmost tuple element first!!!
lst.sort(key = itemgetter(0), reversed = True)
lst.sort(key = itemgetter(2,4))

print (lst == sorted_lst) #True -- Results are the same :-)

【讨论】:

  • sorted(student_tuples, key=lambda x: x[2],x[4],-x[0],x[1]) 我收到以下错误消息: SyntaxError: non-keyword关键字 arg 后的 arg
  • @gudge -- 那是因为我忘记了括号。查看更新的答案。
  • 谢谢,它有效。第二种解决方案更优雅,您在链接中的解释非常好。
  • 嗨,我不认为该解决方案有效:x = [(100, 103), (100, 105), (98, 104)] 第一个字段按升序排序:[ (98, 104), (100, 103), (100, 105)] 在第二个字段上按降序排序 [(98, 104), (100, 105), (100, 103)]
  • @gudge -- 如果key 函数在后续排序中返回相同的值,它将只保留第一个排序的顺序。我的两个示例应该是等价的(注意在多排序上下文中,我使用最右边的索引 (1) 作为排序键 first)。
【解决方案2】:

您可以创建一个具有有意义的属性名称的类,而不仅仅是数字索引;如果你给它__cmp__(python 2.x)或__eq__和__lt__加上@total_ordering(python 3.x),那将很容易排序。

另一种选择是保留元组,将它们转换为列表,并否定您需要反向排序的任何数字字段。您可以对字符串执行此操作,但不如数字那么整洁。

元组排序快的部分原因是它们不是超级灵活。

【讨论】:

  • 您可能想提及在哪里可以找到total_ordering(即functools.total_ordering)
猜你喜欢
  • 2012-04-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-29
相关资源
最近更新 更多