您需要进行两次排序。Python的排序算法是稳定的,这意味着相等的元素会保持它们的相对顺序。首先按第二个元素排序(升序),然后再次排序,只按第一个元素且降序排列:
sorted(sorted(my_list2, key=lambda t: t[1]), key=lambda t: t[0], reverse=True)
使用 operator.itemgetter()
代替 lambda
可以使这个小程序更快(避免每个元素都要返回 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()
函数来应用这些规则。请参考
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))
[('aaa', 'bbb'), ('aaa', 'ccc'), ('bbb', 'aaa'), ('bbb', 'ccc')]
怎么会变成[('bbb', 'aaa'), ('bbb', 'ccc'), ('aaa', 'bbb'), ('aaa', 'ccc')]
吗? - Devesh Kumar Singh