如何在不使用reverse = True参数的情况下以相反顺序对字符串列表进行排序? [英] How to sort a list of strings in reverse order without using reverse=True parameter?

查看:154
本文介绍了如何在不使用reverse = True参数的情况下以相反顺序对字符串列表进行排序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to sort a list of strings in reverse order, e.g.:

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

预期结果:

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

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

I don't want to use sorted(my_list, reverse=True), because in more complex case when filtering by two values it would not work. For example:

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')]

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

It is simple with numbers, you can negate the value:

>>> 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)]

但是如何使用字符串呢?

But how to do it with strings?

推荐答案

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

You'll have to sort twice. Python's sort algorithm is stable, which means that elements that are equal keep their relative order. Use this to first sort on the second element (sorting in ascending order), then sort that output again, on only the first element and in reverse order:

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

使用 operator.itemgetter() 代替lambda s可以使此操作更快(避免对每个元素都退回到Python解释器):

Using operator.itemgetter() instead of lambdas can make this little bit faster (avoiding stepping back in to the Python interpreter for each element):

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()函数以应用这些:

The general rule is to sort from the innermost element to the outermost element. So for an arbitrary-element-count sort, with a key and a reverse boolean each, you can use the functools.reduce() function to apply these:

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))

这篇关于如何在不使用reverse = True参数的情况下以相反顺序对字符串列表进行排序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆