python - 如何在不使用 reverse=True 参数的情况下以相反的顺序对字符串列表进行排序?
问题描述
我想以相反的顺序对字符串列表进行排序,例如:
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)]
但是如何使用字符串呢?
解决方案
你必须排序两次。Python 的排序算法是稳定的,这意味着相等的元素保持它们的相对顺序。使用它首先对第二个元素进行排序(按升序排序),然后再次对该输出进行排序,仅对第一个元素并以相反的顺序:
sorted(sorted(my_list2, key=lambda t: t[1]), key=lambda t: t[0], reverse=True)
使用operator.itemgetter()
而不是lambda
s 可以使这更快一点(避免为每个元素返回到 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))
推荐阅读
- javascript - 使用 Django 和 HTML 在 chart.js 上显示输出
- python - 根据其他列中给出的值在 pandas 数据帧上生成 n 数量的新行
- html - Html:视频卡img悬停
- python - 将一个函数传递给另一个 TypeError 时出错:“函数”对象不可下标
- mysql - 如何使用 jooq 访问子查询列?
- perl - Perl 将本地时间格式的时间转换为 YYYYMMDD
- ios - iOS 在后台模式下从广告中省略制造商数据
- javascript - 检测移动源 iframe 内的点击
- javascript - 在等待的 Promise 中抛出的错误未在 catch 块中捕获
- c++ - 获取剩余帧数以在 ALSA 中播放