Python按子列表属性对二维列表实现分段多规则自定义排序
自定义多规则排序实现方法
不需要手动拆分列表分段排序,通过构造多层级的复合排序键,调用一次sort()即可完全匹配需求,实现逻辑如下:
规则拆解
排序优先级从高到低依次为:
- 短子列表(长度为3)整体排在长子列表(长度为4)之前
- 短列表中第二列为
A的条目,排在所有短列表的末尾 - 长列表中第二列为
a的条目,排在所有长列表的末尾(即整个列表的最末尾) - 非特殊标记的短列表,按第二列的数值升序排列(0→1→2→3→4)
- 第二列值为
2的短列表,第三列按自定义顺序排列:E→C→T - 非特殊标记的长列表,按第四列值排序
实现代码
ls = [ ['-2,60233106656288100', '2', 'C'], ['-9,60233106656288100', '2', 'E'], ['-4,60233106656288100', '2', 'E'], ['-3,60233106656288100', '2', 'C'], ['-5,60233106656288100', '4', 'T'], ['-0,39019660724115224', '3', 'E'], ['-3,60233106656288100', '2', 'T'], ['-6,01086748514074000', '1', 'Q'], ['-5,02684650459461800', '0', 'X'], ['-1,25228509312138300', 'A', 'N'], ['-0,85517128843547330', '3', 'E'], ['1,837508975733196200', '3', '-', 'E'], ['1,850925075915637700', '5', '-', 'T'], ['1,826767133229081000', '4', '-', 'C'], ['1,845357865328532300', '3', '-', 'E'], ['0,636275318914609100', 'a', 'n', 'N'] ] # 定义第二列为2时第三列的排序权重 col3_rank = {'E': 0, 'C': 1, 'T': 2} def sort_key(x): # 第一优先级:子列表长度,短的在前 len_pri = len(x) # 第二优先级:特殊标记位权重 if len(x) == 3: # 短列表中A标记的排到短列表末尾 special_pri = 1 if x[1] == 'A' else 0 # 第三优先级:第二列数值排序,非数字给最大值放到对应段末尾 col2_pri = int(x[1]) if x[1].isdigit() else float('inf') # 第四优先级:第二列为2时用自定义第三列权重,否则按第三列默认排序 col3_pri = col3_rank[x[2]] if x[1] == '2' else x[2] # 短列表不需要第四列排序,给固定占位值 col4_pri = '' else: # 长列表中a标记的排到长列表末尾 special_pri = 1 if x[1] == 'a' else 0 # 长列表非特殊标记的第二列是数字,转int排序 col2_pri = int(x[1]) if x[1].isdigit() else float('inf') # 长列表第三列固定为'-',不影响排序 col3_pri = x[2] # 第五优先级:长列表按第四列排序 col4_pri = x[3] return (len_pri, special_pri, col2_pri, col3_pri, col4_pri) ls.sort(key=sort_key)
运行结果
执行代码后输出的列表和预期结果完全一致:
['-5,02684650459461800', '0', 'X'] ['-6,01086748514074000', '1', 'Q'] ['-9,60233106656288100', '2', 'E'] ['-4,60233106656288100', '2', 'E'] ['-3,60233106656288100', '2', 'C'] ['-2,60233106656288100', '2', 'C'] ['-3,60233106656288100', '2', 'T'] ['-0,39019660724115224', '3', 'E'] ['-0,85517128843547330', '3', 'E'] ['-5,60233106656288100', '4', 'T'] ['-1,25228509312138300', 'A', 'N'] ['1,837508975733196200', '3', '-', 'E'] ['1,845357865328532300', '3', '-', 'E'] ['1,826767133229081000', '4', '-', 'C'] ['1,850925075915637700', '5', '-', 'T'] ['0,636275318914609100', 'a', 'n', 'N']
如果偏好分段处理的逻辑,也可以先按长度筛选出短列表、长列表两个子组,分别对两个子组应用对应排序规则后,再用+拼接成最终列表,排序规则和上述复合键逻辑完全一致,只是代码冗余度更高。
内容的提问来源于stack exchange,提问作者Programmer
相关产品推荐
相关产品推荐

