如何在不使用reverse = True参数的情况下以相反顺序对字符串列表进行排序?

发布于 2021-01-29 15:05:04

我想以相反的顺序对字符串列表进行排序,例如:

my_list = ['aaa', 'bbb', 'ccc']

预期结果:

['ccc', 'bbb', 'aaa']

我不想使用sorted(my_list, reverse=True),因为在更复杂的情况下,按两个值进行过滤将无法正常工作。例如:

my_list2 = [('aaa', 'bbb'), ('aaa', 'ccc'), ('bbb', 'aaa'), ('bbb', 'ccc')]

预期结果将是:

[('bbb', 'aaa'), ('bbb', 'ccc'), ('aaa', 'bbb'), ('aaa', 'ccc')]

sorted(my_list2, reverse=True) 返回:

[('bbb', 'ccc'), ('bbb', 'aaa'), ('aaa', 'ccc'), ('aaa', 'bbb')]

数字很​​简单,您可以取反值:

>>> my_list3 = [(1, 2), (1, 3), (2, 1), (2, 3)]
>>> sorted(my_list3, key=lambda x: (-x[0], x[1]))
... [(2, 1), (2, 3), (1, 2), (1, 3)]

但是如何使用字符串呢?

关注者
0
被浏览
80
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    您将不得不排序两次。Python的sort算法 稳定
    ,这意味着相等的元素保持其相对顺序。使用它首先对第二个元素进行排序(以升序排序),然后仅对第一个元素以相反的顺序再次对输出进行排序:

    sorted(sorted(my_list2, key=lambda t: t[1]), key=lambda t: t[0], reverse=True)
    

    使用operator.itemgetter()而不是lambdas可以使速度更快(避免对每个元素退回到Python解释器):

    from operator import itemgetter
    
    sorted(sorted(my_list2, key=itemgetter(1)), key=itemgetter(0), reverse=True)
    

    演示:

    >>> from operator import itemgetter
    >>> my_list2 = [('aaa', 'bbb'), ('aaa', 'ccc'), ('bbb', 'aaa'), ('bbb', 'ccc')]
    >>> sorted(sorted(my_list2, key=lambda t: t[1]), key=lambda t: t[0], reverse=True)
    [('bbb', 'aaa'), ('bbb', 'ccc'), ('aaa', 'bbb'), ('aaa', 'ccc')]
    >>> sorted(sorted(my_list2, key=itemgetter(1)), key=itemgetter(0), reverse=True)
    [('bbb', 'aaa'), ('bbb', 'ccc'), ('aaa', 'bbb'), ('aaa', 'ccc')]
    

    一般规则是从最内层元素到最外层元素排序。因此,对于任意元素计数排序(每个都有一个键和一个反向布尔值),可以使用该functools.reduce()函数来应用它们:

    from functools import reduce
    from operator import itemgetter
    
    def sort_multiple(sequence, *sort_order):
        """Sort a sequence by multiple criteria.
    
        Accepts a sequence and 0 or more (key, reverse) tuples, where
        the key is a callable used to extract the value to sort on
        from the input sequence, and reverse is a boolean dictating if
        this value is sorted in ascending or descending order.
    
        """
        return reduce(
            lambda s, order: sorted(s, key=order[0], reverse=order[1]),
            reversed(sort_order),
            sequence
        )
    
    sort_multiple(my_list2, (itemgetter(0), True), (itemgetter(1), False))
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看