Python实现元组列表先按第0位升序再按第1位降序排序
实现元组列表的多条件排序(先按第0位升序,再按第1位降序)
给定待排序的列表:
L = [(1, 'a'), (4, 'k'), (3, 'p'), (3, 'q'), (2, 'a'), (2, 'b'), (1, 'z')]
你尝试的L.sort(key=lambda x: (x[0], -x[1]))方法失效,是因为字符串无法直接取反。下面提供三种可行的实现方式:
方案1:利用稳定排序分两次排序
Python的list.sort()是稳定排序——相同排序key的元素会保留原有的相对顺序。基于这个特性,我们可以先按第1个元素降序排序,再按第0个元素升序排序:
# 先按元组第1位降序排列 L.sort(key=lambda x: x[1], reverse=True) # 再按元组第0位升序排列,此时相同第0位的元素会维持之前的降序顺序 L.sort(key=lambda x: x[0])
最终排序结果:
[(1, 'z'), (1, 'a'), (2, 'b'), (2, 'a'), (3, 'q'), (3, 'p'), (4, 'k')]
方案2:对字符串的ASCII码取反构造key
如果元组的第1位是单个字符,可以通过ord()获取其ASCII码值,再取反作为排序key的一部分,间接实现降序:
L.sort(key=lambda x: (x[0], -ord(x[1])))
如果是多字符字符串,只需对每个字符的ASCII码取反组成元组即可:
# 适配多字符字符串的通用写法 L.sort(key=lambda x: (x[0], tuple(-ord(c) for c in x[1])))
方案3:自定义比较函数(Python 3+)
借助functools.cmp_to_key工具,将自定义的比较逻辑转换为sort可识别的key:
from functools import cmp_to_key def tuple_compare(a, b): # 优先按第0位升序比较 if a[0] != b[0]: return a[0] - b[0] # 第0位相同时,按第1位降序比较 else: return -1 if a[1] > b[1] else 1 if a[1] < b[1] else 0 L.sort(key=cmp_to_key(tuple_compare))
内容的提问来源于stack exchange,提问作者alekscooper
相关产品推荐
相关产品推荐

