Python 按location规则排序嵌套字典生成的列表
实现方法
你遇到的乱序问题有两个原因:一是Python 3.7之前的原生字典不保证插入顺序,二是就算字典保序,原字典的存储顺序也不符合你要求的按location排序的规则,直接遍历取值后加自定义排序逻辑即可。
排序核心是给每个设备条目生成可比较的排序元组,按优先级规则设置权重:
location为MDF的设备权重最高,排在最前- 占位的
...条目放在MDF设备之后、IDF设备之前 IDF开头的设备权重最低,提取后缀的数字转成整数,按数值升序排列,避免字符串字典序导致的排序错误(比如字符串排序下IDF10会排在IDF2前面)
完整代码
# 原遍历取值逻辑可以简化,直接取字典values即可,和你原来写的循环效果完全一致 dev_list = list(dev_dict.values()) def get_sort_key(device): loc = device["location"] if loc == "MDF": # 第一维度权重0,优先级最高;第二维度填0即可,MDF内部无排序要求 return (0, 0) elif loc == "...": # 占位条目权重1,排在MDF之后 return (1, 0) elif loc.startswith("IDF"): # IDF条目权重2,提取后缀数字转整数作为第二排序维度 # 兼容Python3.9以下版本的话,把loc.removeprefix("IDF")换成loc[3:]即可 idf_number = int(loc.removeprefix("IDF")) return (2, idf_number) # 按自定义规则排序 dev_list = sorted(dev_list, key=get_sort_key)
可选精简写法
如果不需要单独维护排序函数,也可以直接用lambda表达式写在sorted参数里,适合逻辑简单的场景:
dev_list = sorted( dev_dict.values(), key=lambda d: ( 0 if d["location"] == "MDF" else 1 if d["location"] == "..." else 2, int(d["location"][3:]) if d["location"].startswith("IDF") else 0 ) )
注意:排序后MDF组内的设备顺序会和原字典中MDF条目的存储顺序一致,如果需要给MDF设备也加排序规则(比如按hostname排序),只要修改对应元组的第二维度返回值即可。
内容的提问来源于stack exchange,提问作者Ryan Bell
相关产品推荐
相关产品推荐

