端口列表范围合并优化求助:现有代码输出不符合预期
端口列表排序与范围缩减问题解决方案
先看你遇到的问题:现有代码输出不符合预期,核心问题出在没有按端口前缀分组,以及排序和范围合并逻辑错误,咱们一步步来修正。
现有代码的问题分析
- 前缀丢失且被覆盖:你每次循环都把
portindex设为当前端口的前缀,但最后portindex会变成最后一个端口的前缀(也就是2/1/),所以所有生成的范围都用了这个错误的前缀。 - 仅排序最后一位数字:你只提取了端口的最后一位排序,但没有考虑前面的网段部分(比如
1/1/和2/1/是不同组),导致跨组的端口被错误合并。 - 范围合并逻辑不完善:相邻两个端口就生成一个范围,会出现重复的中间条目(比如
1-2和2-3),没有合并成完整的1-3。
修正后的代码
from itertools import groupby ports = ["1/1/1","1/1/3","2/1/5", "1/1/2", "2/1/6"] def compress_ports(port_list): # 1. 拆分每个端口为(前缀,端口号整数),并按前缀+端口号排序 split_ports = [] for port in port_list: parts = port.split("/") prefix = "/".join(parts[:2]) + "/" # 得到类似"1/1/"的前缀 port_num = int(parts[-1]) split_ports.append( (prefix, port_num) ) # 按前缀排序,同一前缀内按端口号排序 split_ports.sort(key=lambda x: (x[0], x[1])) compressed = [] # 2. 按前缀分组处理 for prefix, group in groupby(split_ports, key=lambda x: x[0]): port_nums = [num for _, num in group] if not port_nums: continue # 3. 合并连续的端口号为范围 start = end = port_nums[0] for num in port_nums[1:]: if num == end + 1: end = num else: # 加入当前范围 if start == end: compressed.append(f"{prefix}{start}") else: compressed.append(f"{prefix}{start}-{end}") start = end = num # 处理最后一个范围 if start == end: compressed.append(f"{prefix}{start}") else: compressed.append(f"{prefix}{start}-{end}") return compressed print(compress_ports(ports)) # 输出: ['1/1/1-3', '2/1/5-6']
代码解释
- 端口拆分与排序:把每个端口拆分成前缀(比如
1/1/)和整数类型的端口号,然后先按前缀排序,同一前缀内按端口号排序,确保同网段的端口放在一起且有序。 - 按前缀分组:用
itertools.groupby把同一前缀的端口号归为一组,这样不同网段的端口不会被错误合并。 - 连续范围合并:在每组内,跟踪当前范围的起始和结束端口号,当遇到不连续的端口时,就把当前范围加入结果列表,最后处理完所有端口后再加入最后一个范围。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

