Python 3.11.3中如何按group_items顺序重排grouped_items字典
问题:按group_items的出现顺序重排grouped_items的键
我有一个初始字典grouped_items,通过以下代码填充:
grouped_items = { "tcp_permit": [], "tcp_deny": [], "udp_permit": [], "udp_deny": [], "ip_permit": [], "ip_deny": [], "icmp_permit": [], "icmp_deny": [] } group_items = ['_7_tcp_permit_bgp', '_8_icmp_permit_', '_9_udp_permit_domain', '_10_ip_permit_'] separators = ['tcp_permit','tcp_deny', 'udp_permit','udp_deny', 'ip_permit','ip_deny', 'icmp_permit','icmp_deny'] for item in group_items: for separator in separators: if separator in item: grouped_items[separator].append(item) break
填充后得到的grouped_items如下:
grouped_items = { "tcp_permit": [ "_7_tcp_permit_bgp" ], "udp_permit": [ "_9_udp_permit_domain" ], "ip_permit": [ "_10_ip_permit_" ], "icmp_permit": [ "_8_icmp_permit_" ] }
我的目标是让grouped_items的键顺序与group_items中对应项的出现顺序一致,期望结果如下:
grouped_items = { "tcp_permit": [ "_7_tcp_permit_bgp" ], "icmp_permit": [ "_8_icmp_permit_" ], "udp_permit": [ "_9_udp_permit_domain" ], "ip_permit": [ "_10_ip_permit_" ] }
我尝试了以下代码但未成功:
item_order = {item: index for index, item in enumerate(group_items)} sorted_grouped_items = {key: grouped_items[key] for key in sorted(grouped_items, key=lambda x: item_order.get(x, float('inf')))}
请问在Python 3.11.3中,是否可以基于字典的值而非键来重排字典,以实现上述目标?
解决方案
之前的代码失败是因为item_order的键是group_items里的完整字符串(比如_7_tcp_permit_bgp),但排序时用的是grouped_items的键(比如tcp_permit),两者不匹配导致排序逻辑失效。以下是几种可行的实现方式:
方法1:基于值中的元素排序(直接匹配你的需求)
可以通过字典值里的元素,去group_items中查找它的索引,以此作为排序依据:
sorted_grouped_items = { k: v for k, v in sorted( grouped_items.items(), key=lambda item: group_items.index(item[1][0]) ) }
这个逻辑直接利用了每个键对应列表里的唯一元素(比如tcp_permit对应["_7_tcp_permit_bgp"]),通过group_items.index()获取该元素的出现位置,以此排序键值对,完全符合你的期望。
方法2:先构建键的顺序映射再排序
先遍历group_items,为每个grouped_items的键记录它首次出现的位置,再按这个位置排序:
# 构建键与group_items索引的映射 key_order = {} for idx, item in enumerate(group_items): for sep in separators: if sep in item: if sep not in key_order: key_order[sep] = idx break # 按索引排序grouped_items的键 sorted_grouped_items = {k: grouped_items[k] for k in sorted(grouped_items.keys(), key=lambda x: key_order[x])}
方法3:填充时直接维护有序字典
Python 3.7+的普通字典已经保留插入顺序,所以可以在填充时直接构建有序结构,避免后续排序:
grouped_items = {} for item in group_items: for sep in separators: if sep in item: if sep not in grouped_items: grouped_items[sep] = [] grouped_items[sep].append(item) break
这样得到的grouped_items天然就是group_items对应项的出现顺序,无需额外处理。
内容的提问来源于stack exchange,提问作者as path prepend
相关产品推荐
相关产品推荐

