【问题标题】:Sort list of lists ascending and then descending排序列表升序然后降序
【发布时间】:2011-10-03 18:00:23
【问题描述】:

如果我有一个列表,其中包含如下所示的列表

['a',1] ['a',2] ['a',3] ['b',1] ['b',2] ['b',3]

如何对它们进行排序,以便元素 0 降序排序,元素 1 升序排序,这样结果看起来像

['b',1] ['b',2] ['b',3] ['a',1] ['a',2] ['a',3]

使用 itemgetter 我可以在元素 0 上反向传递,但然后我使用元素当然会破坏之前的排序。我不能做一个组合键,因为它需要先降序然后升序。

【问题讨论】:

    标签: python sorting


    【解决方案1】:
    L = [['a',1], ['a',2], ['a',3], ['b',1], ['b',2], ['b',3]]
    L.sort(key=lambda k: (k[0], -k[1]), reverse=True)
    

    L 现在包含:

    [['b', 1], ['b', 2], ['b', 3], ['a', 1], ['a', 2], ['a', 3]]
    

    【讨论】:

    • 我会尽快接受。这正是我所需要的。我正在为我们仓库中的拣选清单处理仓位/仓库路由问题,这成功了。如果你有时间,你能解释一下“lambda k: (k[0],-k[1])”的作用吗?负号是否意味着相反?如果没有反向参数,我可以用 lambda k: (-k[0], k[1]) 得到相同的结果吗?
    • @Ominus:-k[1] 翻转整数上的符号,从而反转它们的自然排序顺序。你不能做-k[0],因为那个值是一个字符串。因此,reverse=True 反转排序顺序,-k[1] 取消了第二个元素的反转。
    【解决方案2】:

    可以进行连续几轮排序,因为 python 的 sortstable。不过,您需要先对 辅助键 进行排序。另请参阅official HOW TO

    from operator import itemgetter
    l = [['a',2], ['a',1], ['b', 2], ['a',3], ['b',1], ['b',3]]
    l.sort(key=itemgetter(1))
    l.sort(key=itemgetter(0), reverse=True)
    # [['b', 1], ['b', 2], ['b', 3], ['a', 1], ['a', 2], ['a', 3]]
    

    【讨论】:

    • 如果第二个排序键没有相反的值(如时间、字符串...),这将是可行的方法,因为在这种情况下无法使用已接受的答案。
    【解决方案3】:

    类似

    def mycmp(a, b):
    
      res = cmp(a[0], b[0])
      if res == 0:
         return cmp(a[1], b[1])
      return res
    
    newlist = sorted(input_list, cmp=mycmp)
    

    比较方法首先检查每个元素的第一项。如果它们相等,它将检查每个元素的第二项。为了实现不同的排序行为,mycmp() 实现中的返回值可能会被取反。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      相关资源
      最近更新 更多