【问题标题】:python: how to sort a complex list on two different keyspython:如何对两个不同键的复杂列表进行排序
【发布时间】:2010-10-20 16:00:18
【问题描述】:

我有一个按以下方式构建的奇怪列表:

[[name_d, 5], [name_e, 10], [name_a, 5]] 

我想先按数字(desc)对其进行排序,然后,如果数字相同,则按名称(asc)。所以我想要的结果是:

[[name_e, 10], [name_a, 5], [name_d, 5]]

我试着想出一个可以在 sort 方法中使用的 lambda 函数,但我不确定我能不能做到。

【问题讨论】:

标签: python sorting


【解决方案1】:

python 中的排序函数允许将函数作为排序键传递:

l = [[name_d, 5], [name_e, 10], [name_a, 5]]
# copy
l_sorted = sorted(l, key=lambda x: (x[1] * -1, x[0]))
# in place
l.sort(key=lambda x: (x[1] * -1, x[0]))

编辑:
1.排序顺序
2. 演示复制和就地排序

【讨论】:

  • 他需要对数字进行降序排序
  • 这不能按我想要的方式工作,因为它还在 desc(或 asc)模式下对名称进行排序
  • @Giovanni:这不是黑匣子。你看它是如何解决的?并且您无法修改它以适应您的问题?
  • 顺便说一句:如果你不想复制列表L l.sort(key=lambda...)
  • 它解决了我的问题。但我不明白 x[1] * -1 是什么意思。一个解释会更好。
【解决方案2】:

您可以对列表进行两次排序以获得结果,只需颠倒顺序即可:

import operator

l = [[name_d, 5], [name_e, 10], [name_a, 5]]

l.sort(operator.itemgetter(1))
l.sort(operator.itemgetter(0), reverse=True)

然后你会得到预期的排序列表。

【讨论】:

    【解决方案3】:

        这是我精心设计的(用于解决相同类型的问题)。我只用我安装的最新版本的 Python (OS X) 检查了它。下面的导入部分是(命名笨拙的)排序键:sortKeyWithTwoListOrderssortKeyWith2ndThen1stListValue


    #Tested under Python 2.7.1 & Python 3.2.3:
    
    import random # Just to shuffle for demo purposes
    
    # Our two lists to sort
    firstCol=['abc','ghi','jkl','mno','bcd','hjk']
    secondCol=[5,4,2,1]
    
    # Build 2 dimensional list [[firstCol,secondCol]...]
    myList = []
    for firstInd in range(0, len(firstCol)):
      for secondInd in range(0, len(secondCol)):
        myList = myList + [[firstCol[firstInd],secondCol[secondInd]]]
    
    random.shuffle(myList)
    
    print ("myList (shuffled):")
    for i in range(0,len(myList)):
      print (myList[i])
    
    def sortKeyWithTwoListOrders(item):
      return secondCol.index(item[1]), firstCol.index(item[0])
    
    myList.sort(key=sortKeyWithTwoListOrders)
    print ("myList (sorted according to strict list order, second column then first column):")
    for i in range(0,len(myList)):
      print (myList[i])
    
    random.shuffle(myList)
    
    print ("myList (shuffled again):")
    for i in range(0,len(myList)):
      print (myList[i])
    
    def sortKeyWith2ndThen1stListValue(item):
      return item[1], item[0]
    
    myList.sort(key=sortKeyWith2ndThen1stListValue)
    print ("myList (sorted according to *values*, second column then first column):")
    for i in range(0,len(myList)):
      print (myList[i])
    

    myList (shuffled):
    ['ghi', 5]
    ['abc', 2]
    ['abc', 1]
    ['abc', 4]
    ['hjk', 5]
    ['bcd', 4]
    ['jkl', 5]
    ['jkl', 2]
    ['bcd', 1]
    ['ghi', 1]
    ['mno', 5]
    ['ghi', 2]
    ['hjk', 2]
    ['jkl', 4]
    ['mno', 4]
    ['bcd', 2]
    ['bcd', 5]
    ['ghi', 4]
    ['hjk', 4]
    ['mno', 2]
    ['abc', 5]
    ['mno', 1]
    ['hjk', 1]
    ['jkl', 1]
    myList (sorted according to strict list order, second column then first column):
    ['abc', 5]
    ['ghi', 5]
    ['jkl', 5]
    ['mno', 5]
    ['bcd', 5]
    ['hjk', 5]
    ['abc', 4]
    ['ghi', 4]
    ['jkl', 4]
    ['mno', 4]
    ['bcd', 4]
    ['hjk', 4]
    ['abc', 2]
    ['ghi', 2]
    ['jkl', 2]
    ['mno', 2]
    ['bcd', 2]
    ['hjk', 2]
    ['abc', 1]
    ['ghi', 1]
    ['jkl', 1]
    ['mno', 1]
    ['bcd', 1]
    ['hjk', 1]
    myList (shuffled again):
    ['hjk', 4]
    ['ghi', 1]
    ['abc', 5]
    ['bcd', 5]
    ['ghi', 4]
    ['mno', 1]
    ['jkl', 1]
    ['abc', 1]
    ['hjk', 1]
    ['jkl', 2]
    ['hjk', 5]
    ['mno', 2]
    ['jkl', 4]
    ['ghi', 5]
    ['bcd', 1]
    ['bcd', 2]
    ['jkl', 5]
    ['abc', 2]
    ['hjk', 2]
    ['abc', 4]
    ['mno', 4]
    ['mno', 5]
    ['bcd', 4]
    ['ghi', 2]
    myList (sorted according to *values*, second column then first column):
    ['abc', 1]
    ['bcd', 1]
    ['ghi', 1]
    ['hjk', 1]
    ['jkl', 1]
    ['mno', 1]
    ['abc', 2]
    ['bcd', 2]
    ['ghi', 2]
    ['hjk', 2]
    ['jkl', 2]
    ['mno', 2]
    ['abc', 4]
    ['bcd', 4]
    ['ghi', 4]
    ['hjk', 4]
    ['jkl', 4]
    ['mno', 4]
    ['abc', 5]
    ['bcd', 5]
    ['ghi', 5]
    ['hjk', 5]
    ['jkl', 5]
    ['mno', 5]
    

    【讨论】:

      【解决方案4】:

      让我们给你的列表起个名字 - “arr”

      arr=sort(key=lambda x:x[1],reverse=True)
      

      输出 - [[name_e,10],[name_d,5],[name_a,5]]

      【讨论】:

        【解决方案5】:

        它不需要是你传递给sort方法的lambda函数,你实际上可以提供一个真正的函数,因为它们是python中的一等对象。

        L.sort(my_comparison_function)
        

        应该没问题

        【讨论】:

        • -1 比较函数在 Python 3 中消失了,而另一个答案是未来证明。
        • 我想过这个问题,但是如何编写一个适用于两个不同键的比较函数呢?基本上我需要一个 f((x[0],x[1]), (y[0],y[1]))
        • @Steven:你在说什么?这个答案可能没用,但不是因为你所说的原因。 Read the docs
        • @SilentGhost 也许我读错了,但是当我查看链接的文档时,我发现 sort 接受 python 3 中的 /key/ 函数,但不接受 /comparison/ 函数。
        • @SilentGhost 对项目对调用比较函数,“如果 self other 则返回正整数。”而对于每个项目调用一次键函数并返回您希望对项目进行排序的值。请参阅 wiki.python.org/moin/HowTo/Sorting,特别注意标题为 Key_FunctionsThe_Old_Way_Using_the_cmp_Parameter 的部分。关键参数是在 Python 2.4 中添加的。在 Python 3 中删除了 cmp 参数。
        猜你喜欢
        • 1970-01-01
        • 2013-11-02
        • 2015-04-14
        • 2012-11-20
        • 1970-01-01
        • 1970-01-01
        • 2023-02-26
        • 2020-11-06
        • 2012-10-20
        相关资源
        最近更新 更多