如何对包含数字的点分隔命令字符串列表进行自然排序
点分隔命令字符串自然排序解决方案
问题描述
你有一组由.分隔的命令字符串,示例如下:
DeviceA.CommandA.1.Hello, DeviceA.CommandA.2.Hello, DeviceA.CommandA.11.Hello, DeviceA.CommandA.3.Hello, DeviceA.CommandB.1.Hello, DeviceA.CommandB.1.Bye, DeviceB.CommandB.What, DeviceA.SubdeviceA.CommandB.1.Hello, DeviceA.SubdeviceA.CommandB.2.Hello, DeviceA.SubdeviceB.CommandA.1.What
需要遵循以下规则排序:
- 优先按字段的先后顺序比较,例如
DeviceA开头的命令永远排在DeviceB开头的命令前 - 纯字符串字段按字母顺序排序
- 纯数字字段按数值升序排序
最终期望输出:
DeviceA.CommandA.1.Hello, DeviceA.CommandA.2.Hello, DeviceA.CommandA.3.Hello, DeviceA.CommandA.11.Hello, DeviceA.CommandB.1.Bye, DeviceA.CommandB.1.Hello, DeviceA.SubdeviceA.CommandB.1.Hello, DeviceA.SubdeviceA.CommandB.2.Hello, DeviceA.SubdeviceB.CommandA.What, DeviceB.CommandB.What
注意命令的字段长度不固定,.分隔的字段数量是动态的。你之前的实现直接按分割后的字符串元组排序,会导致数字按字符顺序排列,比如11会排在3前面,不符合要求。
解决方案
核心思路是自定义排序key,对每个分割后的字段做类型判断:如果是纯数字就转换为整数,否则保留原字符串,这样排序时会自动匹配规则要求。
代码实现
cmd_list = [ "DeviceA.CommandA.1.Hello", "DeviceA.CommandA.2.Hello", "DeviceA.CommandA.11.Hello", "DeviceA.CommandA.3.Hello", "DeviceA.CommandB.1.Hello", "DeviceA.CommandB.1.Bye", "DeviceB.CommandB.What", "DeviceA.SubdeviceA.CommandB.1.Hello", "DeviceA.SubdeviceA.CommandB.2.Hello", "DeviceA.SubdeviceB.CommandA.1.What" ] sorted_list = sorted( cmd_list, key=lambda x: tuple(int(part) if part.isdigit() else part for part in x.split('.')) )
逻辑说明
- 按
.分割每个命令字符串得到字段列表,逐个判断字段是否为纯数字,是则转成int类型,否则保留原字符串,最后封装为元组作为排序key - 元组默认按位置先后比较元素,天然满足优先按前面字段排序的要求
- 相同类型的元素会按对应规则排序:字符串按字母序,int按数值升序
- 对于长度不同的字段元组,Python默认规则是前面元素全部相等时,更短的元组排在前面,符合动态字段长度的排序预期
内容的提问来源于stack exchange,提问作者Eduardo G
相关产品推荐
相关产品推荐

