【问题标题】:Python: How to perform a secondary descending alphabetic sort within a numeric primary sortPython:如何在数字主要排序中执行次要降序字母排序
【发布时间】:2016-02-14 13:52:41
【问题描述】:

Sorting a Python list by two criteriaFouad 给出了以下答案:

sorted(list, key=lambda x: (x[0], -x[1]))

我想主要在元组列表中对以下列表进行排序,主要在每个元素中的第二个项目上按升序排列,然后是第一个(字母)项目按降序排列:

[('Ayoz', 1, 18, 7), ('Aidan', 2, 4, 9), ('Alan', 2, 4, 9), ('Arlan', 5, 6, 7), ('Luke', 15, 16, 2), ('Tariq', 5, 4, 2)] 

给出答案:

[('Ayoz', 1, 18, 7), ('Alan', 2, 4, 9), ('Aidan', 2, 4, 9), ('Tariq', 5, 4, 2), ('Arlan', 5, 6, 7), ('Luke', 15, 16, 2)]

尽可能使用上述方法。 我试过了

tlist = [('Ayoz', 1, 18, 7), ('Aidan', 2, 4, 9), ('Alan', 2, 4, 9), ('Arlan', 5, 6, 7), ('Luke', 15, 16, 2), ('Tariq', 5, 4, 2)]
sorted(tlist, key=lambda elem: (elem[1], -elem[0]))

但这仅在 elem[0] 为数字时有效(在这种情况下,它会给出 TypeError: bad operand type for unary -: 'str')

如有任何帮助,我将不胜感激。 Python 版本是 3.4

【问题讨论】:

    标签: python sorting python-3.x


    【解决方案1】:
    tlist = [('Ayoz', 1, 18, 7), ('Alan', 2, 4, 9), ('Aidan', 2, 4, 9), ('Arlan', 5, 6, 7), ('Luke', 15, 16, 2), ('Tariq', 5, 4, 2)] 
    
    sorted(tlist, key=lambda elem: (elem[1],sorted(elem[0],reverse=True)))
    

    解决了,但我花了半个小时才打字,所以无论如何我都会发帖。我仍然欢迎更好的方法。

    【讨论】:

      【解决方案2】:

      您可以修改原始答案以使其发挥作用:

      sorted(tlist, key=lambda elem: (-elem[1], elem[0]), reverse=True)
      

      【讨论】:

      • 我知道它说不要使用 cmets 表示感谢,但不这样做似乎很粗鲁。谢谢。我想我更喜欢你的更简单排序的方法(如果你对两个或多个字符串元素进行排序,其中一些是升序的,其他的是降序的,它就行不通了)。
      【解决方案3】:

      Python 中内置的排序例程是稳定的。也就是说,如果两个项目具有相同的键值,那么它们将保持它们相对于彼此的顺序(靠近列表前面的那个保持更靠近前面)。因此,您可以使用多个排序通道对多个键进行排序。

      from operator import itemgetter
      
      tlist = [('Ayoz', 1, 18, 7), ('Aidan', 2, 4, 9), ('Alan', 2, 4, 9),
               ('Arlan', 5, 6, 7), ('Luke', 15, 16, 2), ('Tariq', 5, 4, 2)]
      
      # sort by name in descending order
      tlist.sort(key=itemgetter(0), reverse=True) 
      print('pass 1:', tlist)
      
      # sort by element 1 in ascending order.  If two items have the same value
      # the names stay in the same order they had (descending order)
      tlist.sort(key=itemgetter(1))
      print(npass 2:', tlist)
      

      打印:

      pass 1: [('Tariq', 5, 4, 2), ('Luke', 15, 16, 2), ('Ayoz', 1, 18, 7), ('Arlan', 5, 6, 7), ('Alan', 2, 4, 9), ('Aidan', 2, 4, 9)]
      
      pass 2: [('Ayoz', 1, 18, 7), ('Alan', 2, 4, 9), ('Aidan', 2, 4, 9), ('Tariq', 5, 4, 2), ('Arlan', 5, 6, 7), ('Luke', 15, 16, 2)]
      

      【讨论】:

        【解决方案4】:

        这里有一个替代方案。它的工作原理类似于使用 -number 来反转排序顺序的技巧,但适用于字母字符串。

        下表将 'a' 映射到 'z'、'b' 到 'y' 等。t[0].translate(table) 将 'Ayoz' 转换为 'Zbla',因此 ('Ayoz', 1, 18, 7) 是 (1, Zbla')

        table = str.maketrans('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
                              'zyxwvutsrqponmlkjihgfedcbaZYXWVUTSRQPONMLKJIHGFEDCBA')
        
        tlist.sort(key=lambda t: (t[1], t[0].translate(table)))
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-14
          • 2013-06-05
          • 2021-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-04
          相关资源
          最近更新 更多